Linux prosesleri nasıl yönetir?
Bu flood’da Linux işletim sisteminin çalıştırdığı proseslerle etkileşiminden bahsedeceğim.
Linux programlardan prosesler oluşturur ve bu prosesleri çalıştırır. Birçok program çalıştırıldığında sadece tek bir proses oluşturur ancak bazı programlar farklı amaçlar için birden fazla proses oluşturabilirler. Örneğin Google Chrome, açılan her bir tab için yeni bir proses oluşturur. Böylece ziyaret edilen sitelerden (tab) biri kilitlendiğinde programı yeniden açıp kapatmak gerekmez, sadece ilgili tab’daki proses öldürülerek çalışmaya devam edilebilir.
Linux, bütün proseslere birer ID verir ve prosesler Parent Process
adı verilen başka bir proses tarafından oluşturulur. Çalışan bütün prosesleri göstermek için ps -ef
komutu kullanılabilir ve aşağıdaki gibi bir çıktı oluşturur.
Linux çekirdeği açılış sırasında gerekli hazırlıkları tamamladıktan sonra ID’si 1
olan init
prosesini oluşturur o da başka prosesleri oluşturur. Aşağıda sshd
(SSH Daemon) filtrelenerek sshd
prosesinin init
tarafından yaratıldığı gösterilmiştir.
Yukarıda çıktıda görüldüğü gibi PID
'si 948
olan sshd
, PID
'si 1
olan init
tarafından yaratılmıştır. Sonra da sırasıyla 948
, 1506
'yı o da 1529
PID
'li prosesi yaratmıştır. ps axf
veya pstree
ile bahsedilen hiyerarşi aşağıdaki gibi görülebilir.
Yukarıda görüldüğü üzere ssh ile bağlanılan bash
prosesi sshd
tarafından yaratılmıştır. Aynı şekilde bash
üzerinden çalıştırılacak bütün proseslerin parent prosesi bash
olacaktır. Aşağıdaki örnekte 1
'de koşturulan ping
prosesinin parent prosesi bash
olmuştur.
Linux, çalıştırdığı prosesin başarı ile sonuçlanıp sonuçlanmadığını çıkış koduna (Exit Code) bakarak anlayabilir. Çıkış kodu 0
olan proses başarı ile sonuçlanmış, 0
dışındaki bir çıkış kodu ile çıkan proses ise çeşitli nedenlerle başarısız olmuştur.
bash
kabuğunda echo $?
komutu verilerek son çalıştırılan programın çıkış kodu alınabilir. Aşağıdaki örnekte bir klasör iki kere yaratılmak istenmiştir. İlk deneme başarılı olmuş ikinci deneme ise daha önce ilgili klasör bulunduğu için başarısız olmuştur.
Programların çıkış kodları ile ilgili genel bir standart bulunmamakla birlikte yukarıdaki örnekte olduğu gibi uygulamanın iş katmanındaki hatalarda (zaten var olan bir klasörü yaratmaya çalışma veya olmayan bir dosyanın içeriğini döktürme) çıkış kodu genelde 1
olarak verilir.
Prosesin kendi isteği ile sonlanmadığı, işletim sistemi veya kullanıcı tarafından bir sinyalle sonlandırıldığı durumlarda ise çıkış kodu Linux’taki sinyal koduna 128
eklenerek bulunur. Örneğin prosese SIGKILL - 9
sinyali gönderilirse çıkış kodu 128 + 9 = 137
olur.
Aşağıda tail
prosesine SIGTERM - 15
sinyali gönderildiğinde çıkış kodunun 128 + 15 = 143
olduğu görülmektedir. Ek olarak memory sınırı verildiğinde veya sistemde Swap açık değilken çok fazla memory tüketen prosesler Linux tarafından 137
yani SIGKILL
ile öldürülürler.
Linux’ta her şeyin bir dosya olduğunu muhakkak duymuşsunuzdur. Prosesler de Linux tarafından /proc
altındaki dosya sisteminden yönetilirler. Linux her bir proses için prosesin PID'si ile /proc
klasörü altında bir klasör oluşturur, bu klasörde prosesle ilgili bilgiler bulunur.
Aşağıdaki ekran çıktısında bir session’da APP_PURPOSE=Demo
ortam değişkeni verilerek başlatılan tail -f /dev/null
prosesi ile ilgili bilgiler (uygulama parametreleri, bütün ortam değişkenleri) /proc
dosya sisteminden ikinci ekranda döktürülmüştür.
Linux her proses için üç file descriptor - fd
yaratır. İlki stdin/fd 0
, ikincisi stdout/fd 1
üçüncüsü ise stderr/fd 2
'dır . stdin
klavyeden girdi alacak, stdout
ve stderr
ise ekrana çıktı verecek şekilde ayarlanır. Aşağıda bir örnek gösterilmiştir.
Linux’ta yönlendirme yapılırken kullanılan 1, 2
rakamları fd
'leri ifade eder. cmd >> log-output 2>&1
ile önce cmd
'nin stdout
'u log-output'a, sonra da 2>&1
komutu ile stderr/fd 2
, stdout/fd 1
'e yönlendirilmiş böylece stdout
ve stderr
aynı dosyaya yazılmıştır.
En son olarak da C
ile yazılan ve terminalden iki sayı okuyarak bunları toplayıp sonucu ekranda gösteren sum
adlı proses çalışıyorken sum
programını yanlışlıkla diskten silelim ve sonra da /proc/PID/exe
adresinden kopyalayarak geri döndürelim.