SIGKILL sinyali gönderildiğinde bir program ne yapar?


39

Bir killall -9 nameprogramı öldürdüğümde, devlet zombiye dönüşür. Birkaç dakika sonra gerçekten durdu. Peki, bu dakikalarda neler oluyor?

Yanıtlar:


66

Program aslında SIGKILL sinyalini asla almaz, çünkü SIGKILL tamamen işletim sistemi / çekirdek tarafından kullanılır.

Belirli bir işlem için SIGKILL gönderildiğinde, çekirdek zamanlayıcısı derhal bu işleme, kullanıcı-alan kodunu çalıştırmak için daha fazla CPU zamanı vermeyi durdurur. İşlem, zamanlayıcının bu kararı verdiği anda diğer CPU'larda / çekirdeklerde kullanıcı-alan kodunu çalıştıran herhangi bir iş parçacığına sahipse, bu iş parçacığı da durdurulur. (Tek çekirdekli sistemlerde bu daha basitti: sistemdeki tek CPU çekirdeği zamanlayıcıyı çalıştırıyorsa, tanımı gereği işlemi aynı anda yapmıyordu!)

İşlem / iş parçacığı SIGKILL zamanında çekirdek kodunu (örneğin, bir sistem çağrısı veya bellek eşlemeli bir dosyayla ilişkilendirilmiş bir G / Ç işlemi) yürütüyorsa, biraz daha zor olur: yalnızca bazı sistem çağrıları kesilebilir, bu nedenle kernel, sistemi çağırıncaya veya sistemin giriş / çıkış işlemleri çözülene kadar süreci özel bir "ölüyor" durumda olarak işaretler. Bunları çözmek için CPU zamanı her zamanki gibi planlanacaktır. Kesilebilir sistem çağrıları veya G / Ç işlemleri, onları çağıran sürecin uygun durma noktalarında ölüp ölmediğini kontrol eder ve bu durumda erken çıkar. Kesintisiz işlemler tamamlanacak ve kullanıcı-alan koduna dönmeden hemen önce “ölen” durumunu kontrol edecek.

Herhangi bir işlem içi çekirdek rutini çözüldükten sonra, işlem durumu "ölmek" den "ölü" ye değiştirilir ve çekirdek, bir program normal bir şekilde çıktığında olduğu gibi temizlemeye başlar. Temizlik tamamlandığında, 128'den büyük bir sonuç kodu atanır (işlemin bir sinyal tarafından öldürüldüğünü belirtmek için; bu dağınık detaylar için bu cevaba bakınız ) ve işlem "zombi" durumuna geçecektir . Öldürülen sürecin ebeveyni bir SIGCHLD sinyali ile bilgilendirilecektir.

Sonuç olarak, sürecin kendisi bir SIGKILL aldığı bilgiyi fiilen işleme koyma şansını elde edemez.

Bir işlem "zombi" durumundayken, işlemin zaten ölü olduğu anlamına gelir, ancak bunun ana işlemi, wait(2)sistem çağrısını kullanarak ölü işlemin çıkış kodunu okuyarak henüz onaylamadı . Temel olarak, bir zombinin daha fazla tükettiği tek kaynak, işlem tablosunda PID'sini, çıkış kodunu ve işlemin ölümü sırasında bazı diğer "hayati istatistiklerini" tutan bir yuvadır.

Ebeveyn süreci çocuklarının önünde ölürse, öksüz çocuk süreçleri otomatik olarak PID # 1 tarafından kabul edilir wait(2);

Bir zombi işleminin temizlenmesi birkaç dakika sürerse , zombinin ana işleminin işini düzgün yapıp yapmadığını gösterir.

Unix benzeri işletim sistemlerinde zombi problemleri durumunda ne yapılması gerektiğine dair yanıltıcı bir açıklama var: "Zombilerin kendileri için zaten öldükleri için hiçbir şey yapamazsınız. Bunun yerine, kötü zombi ustasını öldürün! " (yani zahmetli zombilerin ana süreci)


5
SIGKILL gönderildiğinde işlem bir çekirdek çağrısındaysa (örneğin, G / Ç yapıyorsa) ne olur?
18'de

9
Kılavuzlar SIGKILL'in yürütülmesi için G / Ç iptal edilir veya G / Ç tamamlanıncaya kadar SIGKILL ertelenir. Bu 'S' ve 'D' uyku durumları arasındaki farktır ps: 'S' I / O içindir, çekirdeğin bir sinyal iletmek için iptal edebilmesini bekler ve 'D' ise bunu yapamaz.
zwol

6
Programın işlem CPU zamanını hemen vermeyi bıraktığını söylemek tam olarak doğru değildir. Sinyal işlemenin çekirdek tarafı hala bu işlem tarafından yürütülür, ancak işlem yalnızca çekirdek kodunu yürütür, böylece programın sinyali asla almadığını söylerken haklısınızdır. Süreç, kaynakların çoğundan sorumlu olan çekirdek kodu yürütecek (açık dosyalar, sanal bellek, vb.) Bu temizleme kodunun son adımları, işlem durumunu zombi olarak değiştirip zamanlayıcıyı çağırmaktır. O zaman bir daha asla programlanmayacak.
kasperd

4
Kılavuzlar Sürecin içinde olabileceği en az dört farklı durum vardır. Şu anda çekirdek kodunu çalıştırıyor olabilir veya üç farklı uyku durumundan birinde uyuyor olabilir. Uyku durumları ölümcül sinyaller dışında kesilebilir, kesilemez veya kesilemez olabilir. Kesintisiz bir uykuda olması durumunda, ihtiyaç duyulduğu sürece uyumaya bırakılır ve yalnızca bir kez uyandığında ölme şansı olur. Diğer iki uyku durumundan birinde olsaydı derhal uyanır ve bunun için uygun bir CPU olduğu anda programlanır.
kasperd

2
@gidds Sonra ne olacağı, çalıştırmakta olduğu çekirdek koduna bağlıdır. Çalışıp çalışmadığına bakılmaksızın veya ilk önce uyandırılması gerektiğinden bağımsız olarak devam etmesi için izin verilen çekirdek kodunu çalıştırmaya başlayabilir. Ve bu çekirdek kodu, sürecin ölmesi ve buna göre davranması gerektiğini söylemekten sorumludur. Çoğu zaman çekirdek kodunda bununla başa çıkmanın doğru yolu, hangi işlevi yürüttüğü işlevden yalnızca bir hata döndürmektir. Çekirdek çağrı yığını çözüldüğünde, sinyal işleme kodu kullanıcı moduna dönmeden hemen önce devralabilir.
kasperd
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.