Bir çocuk sürecinin ebeveyni ile birlikte öldüğü UNIX varyantı var mı?


41

Linux çekirdeği davranışını uzun zamandır araştırıyorum ve bana her zaman açıktı:

Bir süreç öldüğünde, tüm çocukları initsonunda ölünceye kadar işleme (PID 1) geri verilir .

Ancak, son zamanlarda, çekirdekten benden çok daha fazla deneyime sahip biri bana şunu söyledi:

(Kullandığınız sürece süreç sonlandığında, tüm çocuklar da öldüğünde NOHUPonlar geri almak bu durumda init).

Şimdi, buna inanmasam da, emin olmak için hala basit bir program yazdım. Her şey sleepsüreç programlamasına bağlı olduğu için testler için zamana ( ) dayanmamam gerektiğini biliyorum , ancak bu basit durum için, bunun yeterli olduğunu düşünüyorum.

int main(void){
    printf("Father process spawned (%d).\n", getpid());
    sleep(5);

    if(fork() == 0){
        printf("Child process spawned (%d => %d).\n", getppid(), getpid());
        sleep(15);
        printf("Child process exiting (%d => %d).\n", getppid(), getpid());
        exit(0);
    }

    sleep(5);
    printf(stdout, "Father process exiting (%d).\n", getpid());
    return EXIT_SUCCESS;
}

İşte programın çıktısı, pssonuçta her printfgörüşmede ilgili sonuç :

$ ./test &
Father process spawned (435).

$ ps -ef | grep test
myuser    435    392   tty1    ./test

Child process spawned (435 => 436).

$ ps -ef | grep test
myuser    435    392   tty1    ./test
myuser    436    435   tty1    ./test

Father process exiting (435).

$ ps -ef | grep test
myuser    436    1     tty1    ./test

Child process exiting (436).

Şimdi, gördüğünüz gibi, beklediğim gibi davranıyor. Yetim işlemi (436), initölene dek (1) e geri verilir .

Ancak, bu davranışın varsayılan olarak uygulanmadığı UNIX tabanlı bir sistem var mı? Bir sürecin ölümünün hemen tüm çocuklarının ölümünü tetiklediği herhangi bir sistem var mı?

Yanıtlar:


68

Bir süreç sona erdiğinde, tüm çocukları da ölür (NOHUP kullanmazsanız, bu durumda tekrar işe başlarlar).

Bu yanlış. Tamamıyla hatalı. Bunu söyleyen kişi ya yanılmış ya da genel dava ile belirli bir durumu karıştırmıştır.

Bir sürecin ölümünün dolaylı olarak çocuklarının ölümüne neden olabileceği iki yol vardır . Bir terminal kapatıldığında olanlarla ilgilidir. Bir terminal kaybolur (seri hat modem mesele için kesilmiştir çünkü tarihsel olarak, günümüzde genellikle kullanıcının terminal emülatörü pencere kapalı için), bir SIGHUP sinyali olduğunda gönderildiği için kontrol işlemi , tipik olarak, ilk kabuk başladı - bu uç çalışan bu terminalde. Kabuklar normalde bu duruma çıkarak tepki verir. Çıkmadan önce, etkileşimli kullanım amaçlı mermiler, başlattıkları her işe HUP gönderir.

nohupİkinci bir HUP sinyali kaynağını kesen bir kabuktan bir iş başlatmak, çünkü işi daha sonra görmezden gelir ve böylece terminal kaybolduğunda ölmesi söylenmez. HUP sinyallerinin kabuktan işlere ilerlemesini kırmanın diğer yolları, disowneğer varsa (iş, kabuğun iş listesinden çıkarılmışsa) kabuğun yerleşik yapısının kullanılmasını ve çift çatallama (kabuk bir çocuğu fırlatan bir çocuğu fırlatır) içerir. kendiliğinden ve derhal çıkar, kabuğunun torunu hakkında bilgisi yoktur).

Yine, terminalde başlayan işler ana süreçleri (deniz kabuğu) öldüğü için değil, ana işlemlerinin onları öldürmeleri söylendiğinde onları öldürmeye karar vermesi nedeniyle ölmektedir. Ve terminaldeki ilk kabuk, ana işlemi öldüğü için değil, terminali kaybolduğu için (terminalin kabuğun ana işlemi olan bir terminal emülatörü tarafından sağlandığı için olabilir) olabilir.


1
Kontrol grubu olan bir şey var, üçüncü bir yol var. Tek bildiğim, sistemd'in temiz öldürmeleri zorlamak için kullandığı.
o11c

5
@JanHudec Ne karıştırıyorsun düşünüyorum nohupile disown. disownçalışan bir işi iş tablosundan (benzeri bir argüman alarak %1) kaldıran bazı kabuklarda yerleşiktir ve bunun en yararlı yan etkisi, kabuğun alt işleme bir SIGHUP göndermeyeceğidir. nohupSIGHUP'ı görmezden gelen (ve diğer birkaç şeyi yapan) harici bir yardımcı programdır ve komut satırında iletilen komutu başlatır.
Gilles 'SO- kötü olmak'

@Gilles: Hayır, değildim, ama nohupaslında strace 'e bakmak execkomuttan önce sinyali görmezden geliyor .
Jan Hudec

Cevabınız için teşekkür ederim! Modem bağlantılarıyla ilgili özellikle biraz tarihsel arka planı sevdim. En başından beri çekirdeği yanlış anladığım için endişelenmeye başlamıştım ...
John WH Smith

3
Ayrıca, bir programın SIGHUP aldığında çıktığını unutmayın, çünkü SIGHUP için varsayılan sinyal işleyicisi çıkmaktır. Ancak, herhangi bir program ana kabuk onu SIGHUP'a gönderdiğinde çıkmamasına neden olabilecek kendi SIGHUP işleyicisini uygulayabilir.
slebetman

12

Bir süreç sona erdiğinde, tüm çocukları da ölür (NOHUP kullanmazsanız, bu durumda tekrar işe başlarlar).

İşlem bir oturum lideri ise bu doğrudur. Bir oturum lideri öldüğünde, bu oturumun tüm üyelerine bir SIGHUP gönderilir. Uygulamada bu onların çocukları ve onların torunları anlamına gelir.

Bir işlem arayarak oturum lideri yapar setsid. Mermiler bunu kullanır.


Sadece bununla ilgili bir test yaptım, ancak açıkladığınız davranışı yeniden üretemedim ... Bir süreç oluşturdum, yeni bir seans verdim ( fork, ebeveyn sürecini setsidöldürdüm) ve başka bir çocuğu bu yeni seansa davet ettim . Bununla birlikte, ana süreç (yeni oturum lideri) öldüğünde, çocuk hiçbir SIGHUP almadı ve initsonunda çıkıncaya kadar bağlandı .
John WH Smith

Gönderen setpgid(2)man: Bir oturum bir kontrol terminali vardır ve o terminal CLOCAL bayrağı ayarlanmazsa, ve bir terminal mesele oluşursa, o zaman oturum lideri bir SIGHUP gönderilir. Oturum lideri çıkarsa, kontrol terminalinin ön plan işlem grubundaki her bir işleme bir SIGHUP sinyali de gönderilir.
ninjalj

1
@ ninjalj Öyleyse bu cevabın sadece oturum lideri aynı zamanda bir terminalin kontrol süreci ise ve geçerliyse geçerli olduğunu tahmin ediyorum. Herhangi bir terminalden bağımsız olan standart bir oturum lideri, çocuklarını öldürmez. Doğru mu?
John WH Smith,

-1

Öyleyse yukarıdaki posterlerin söylediği, çocuklar ölmez, ebeveyn onları öldürür (ya da sonlandırdıkları bir sinyal gönderir). Yani eğer Veli’yi (1) tüm çocuklarının kaydını tutmaya ve (2) tüm çocuklarına bir sinyal göndermeye programlıyorsanız, istediğinizi elde edebilirsiniz.

Shell'in yaptığı budur ve ana sürecinizin yaptığı şey bu olmalıdır. HUP sinyalini ebeveynde yakalamak gerekebilir, böylece çocukları öldürmek için hala yeterli kontrolünüz olur.


Birçok neden ebeveynin ölmesine neden olabilir. Örneğin ebeveyn SIGKILLed ise çocukların hayatta kalmasını önlemenin bir yolu yoktur.
Emil Jeřábek

-1

Ölen ebeveynler ile biraz ilgili olan cevaplarda bir bit eksik: Bir süreç artık okuma işlemi olmayan bir boruya yazdığında, bir SİGPEPE alır. SIGPIPE için standart eylem sonlandırmadır.

Bu gerçekten de süreçlerin ölmesine neden olabilir. Aslında, programın yesöldüğü standart yoldur .

Yürütürsem

(yes;echo $? >&2)|head -10

benim sistemimde cevap

y
y
y
y
y
y
y
y
y
y
141

ve 141 gerçekten 128 + SIGPIPE:

   SIGPIPE      13       Term    Broken pipe: write to pipe with no
                                 readers

dan man 7 signal.


2
Ancak, borudan okuma işlemi mutlaka (veya genellikle) ebeveyni olmak zorunda değildir. Yani bu gerçekten sorunun sorduğu şeyden çok farklı bir durum.
Barmar
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.