Bir <defunct> süreci nedir ve neden öldürülmez?


180

Krom tarayıcı duyarlı değildi ve onu öldürmeye çalıştım, fakat ortadan kaybolmak yerine sürecin <defunct>hakkı vardı ve öldürülmedi:

görüntü tanımını buraya girin

<defunct>Bir süreç için nedir ve neden öldürülmüyor?


3
Kabul edilen cevap, “ kill -9 PIDçalışmadığını” belirtiyor . Bu kısmen doğrudur: gerçekte NO öldürme işe yarayacaktır. Ayrıca, -9 son çare olarak kullanılmalıdır. Zamanın% 99'u ana sürecin varsayılan olarak öldürülmesi onu öldürür ve tüm çocukları toplar Bir "varsayılan öldürme" bir SIGTERM'dir (-15). -9 (SIGKILL) hayranlarını stackoverflow.com/questions/690415/…
Mike S

Yanıtlar:


172

Çıktınızdan, "feshedilmiş" bir süreç görüyoruz; bu, işlemin görevini tamamladığı veya bozulduğu veya öldürüldüğü anlamına gelir, ancak alt süreçleri hala çalışıyor veya bu üst süreç, alt sürecini izliyor. Bu tür bir işlemi öldürmek için -9 PID'yi öldürmek işe yaramıyor. Onları bu komutla öldürmeyi deneyebilirsin ama tekrar tekrar gösterecek.

Bu geçersiz işlemin ana işleminin hangisi olduğunu belirleyin ve onu öldürün. Bunu bilmek için şu komutu çalıştırın:

ps -ef | grep defunct

UID          PID     PPID       C    STIME      TTY          TIME              CMD
1000       637      27872      0   Oct12      ?        00:00:04 [chrome] <defunct>
1000      1808      1777       0    Oct04     ?        00:00:00 [zeitgeist-datah] <defunct>

Ardından kill -9 637 27872, iptal işleminin geçtiğini doğrulayın ps -ef | grep defunct.


13
“feshedilmiş” süreci öldüremezsiniz. Bir işlem tablosundaki girişinin silinmesini yalnızca üst öğelerini öldürerek hızlandırabilirsiniz.
jfs

57
Ppid 1( init) ise ne olur ? Diyelim ki sadece beklemek zorunda kalacağım?
Luc,

7
Öldürmeyi otomatikleştirmek için, bunu da yapabilirsiniz (çıktıdan hangi baytları keseceğinizi değiştirmeniz gerekebilir):ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill -9
warren

3
@ warren Teşekkürler. Ayrıca ikinci bir iz bırakma yaparak biraz daha kısa ve (imo) daha basit hale getirebilirsiniz. Sadece ilk geçişi değiştirin grep [d]efunctveya benzerini yapın ve kendi kendine eşleşmeyecek.
Thor84no

4
@ warren, bir SIGKILL ile bile feshedilmiş bir süreci öldüremezsiniz. Dahası, öldürmek -9'u oldukça göze çarpmadan kullanıyorsunuz. Stackoverflow.com/questions/690415/… adresine bakın . Eğer feshedilmiş çocukları öldürmek istiyorsan, sen deneyebilirsiniz: parents_of_dead_kids=$(ps -ef | grep [d]efunct | awk '{print $3}' | sort | uniq | egrep -v '^1$'); echo "$parents_of_dead_kids" | xargs kill. kill -9İstediğiniz takdirde , senaryoyu 30 saniye kadar sonra tekrar çalıştırın . (Özellikle öldürülmesine izin vermediğime dikkat edin Init)
Mike S

60

Manuel sayfa ps (1) diyor ki :

İşaretli <defunct>süreçler , ebeveynleri onları doğru bir şekilde tahrip etmediği için kalan ölü süreçlerdir ( "zombiler" olarak adlandırılır ). Bu süreçler init(8)eğer ana süreç çıkarsa tarafından imha edilecektir .

Öldüremezsin çünkü çoktan öldü. Kalan tek şey işlem tablosuna bir giriş :

Unix ve Unix benzeri bilgisayar işletim sistemlerinde, bir zombi işlemi veya geçersiz işlem, yürütmeyi tamamlayan, ancak yine de işlem tablosunda bir girişi olan bir işlemdir. Bu giriş, ebeveyn sürecinin çocuğunun çıkış durumunu okumasına izin vermek için hala gereklidir.

Pek çoğu olmadıkça, bu tür işlemlerin yapılmasına izin vermenin zararı yoktur. Zombiye sonunda (arayarak wait(2)) ebeveyni tarafından yetiştirilir . Orijinal ebeveyn, kendi çıkışından önce ulaşmadıysa, initprocess ( pid == 1) bunu daha sonra yapar. Zombi Süreci sadece:

Sona eren ve bu durumun sona ermesini bekleyen başka bir işleme çıkış durumu bildirildiğinde silinen bir işlem.


1

Teşekkürler Mike S. Sıranızı aldık ve ebeveynleri in.telnetd olan geçersiz işlemleri öldürecek bir senaryo yazdık. Herhangi bir ana işlemi öldürmesini istemedik, sadece bir soruna neden olduğunu bildiğimiz telnetd ve gerektiğinde birden fazla işlemi öldürmek için birden çok kez çalıştıracağız.

# egrep -v '^1$ = Make sure the process is not the init process.
# awk '{print $3}' = Print the parent process.

first_parent_of_first_dead_kid=$(ps -ef | grep [d]efunct | awk '{print $3}' | head -n1 | egrep -v '^1$')
echo "$first_parent_of_first_dead_kid"

# If the first parent of the first dead kid is in.telnetd, then kill it.
if ps -ef | grep $first_parent_of_first_dead_kid | grep in.telnetd;then
        echo "We have a defunct process whose parent process is in.telnetd" | logger -t KILL-DEFUNCT-TELNET
        echo "killing $first_parent_of_first_dead_kid" | logger -t KILL-DEFUNCT-TELNET
        kill $first_parent_of_first_dead_kid 2>&1 | logger -t KILL-DEFUNCT-TELNET
fi

1

Paddington'ın cevabını genişletiyor ..

Çıktınıza göre bir fesat görüyoruz , yani bu çocuk süreci ya görevini tamamlamış ya da bozulmuş ya da öldürülmüş demektir. Ana süreci hala devam ediyor ve ölü çocuğunu görmedi.

kill -9 PID çalışmayacak (zaten ölü).

Bu alt sürecin ebeveyni belirlemek için şu komutu çalıştırın:

ps -ef | grep defunct

 UID  PID **PPID** C STIME TTY TIME     CMD
 1000 637  27872   0 Oct12 ?   00:00:04 [chrome] <defunct>

Ebeveynin kim olduğunu görün: ps ax | grep 27872

İsterseniz ebeveyni öldürebilirsiniz ve feshedilmiş kaybolur. kill -9 27872

JF Sebastian'ın daha teknik bir muhakeme için verdiği cevaba bakınız.


1

@ Paddington'ın cevabını ekleyerek, hızlı kontrol için bu işlevi bashrc'ime ekledim:

defunct(){
    echo "Children:"
    ps -ef | head -n1
    ps -ef | grep defunct
    echo "------------------------------"
    echo "Parents:"
    ppids="$(ps -ef | grep defunct | awk '{ print $3 }')"
    echo "$ppids" | while read ppid; do
        ps -A | grep "$ppid"
    done
}

Gibi bir şey çıktılar:

Çocuk:
UID PID PPID C ZAMAN TTY ZAMAN CMD
kullanıcı 25707 25697 0 Şub26 puan / 0 00:00:00 [sh] 
kullanıcı 30381 29915 0 11:46 pts / 7 00:00:00 grep iptal edildi
------------------------------
Ebeveynler:
25697 puan / 0 00:00:00 npm
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.