Saya telah mempelajari perilaku kernel Linux untuk beberapa waktu sekarang, dan selalu jelas bagi saya bahwa:
Ketika suatu proses mati, semua anak-anaknya diberikan kembali ke
init
proses (PID 1) sampai mereka akhirnya mati.
Namun, baru-baru ini, seseorang dengan pengalaman lebih dari saya dengan kernel mengatakan kepada saya bahwa:
Ketika proses keluar, semua anak-anaknya juga mati (kecuali jika Anda menggunakan
NOHUP
dalam kasus apa mereka kembaliinit
).
Sekarang, meskipun saya tidak percaya ini, saya masih menulis program sederhana untuk memastikannya. Saya tahu saya tidak harus bergantung pada waktu ( sleep
) untuk tes karena semuanya tergantung pada penjadwalan proses, namun untuk kasus sederhana ini, saya pikir itu sudah cukup.
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;
}
Ini adalah output program, dengan ps
hasil terkait setiap kali printf
berbicara:
$ ./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).
Sekarang, seperti yang Anda lihat, ini berperilaku seperti yang saya harapkan. Proses yatim (436) diberikan kembali ke init
(1) sampai mati.
Namun, apakah ada sistem berbasis UNIX di mana perilaku ini tidak berlaku secara default? Apakah ada sistem di mana kematian suatu proses segera memicu kematian semua anak-anaknya?
nohup
dengandisown
.disown
adalah builtin di beberapa shell yang menghapus pekerjaan yang sedang berjalan dari tabel pekerjaan (mengambil argumen seperti%1
), dan efek samping utama yang bermanfaat dari itu adalah bahwa shell tidak akan mengirim SIGHUP ke subproses.nohup
adalah utilitas eksternal yang mengabaikan SIGHUP (dan melakukan beberapa hal lain) kemudian memulai perintah yang diteruskan pada baris perintahnya.nohup
sebenarnya mengabaikan sinyal sebelumexec
perintah.Ini benar jika prosesnya adalah pemimpin sesi. Ketika pemimpin sesi meninggal, SIGHUP dikirim ke semua anggota sesi itu. Dalam praktik itu berarti anak-anak dan keturunan mereka.
Suatu proses menjadikan dirinya sendiri pemimpin sesi dengan menelepon
setsid
. Kerang gunakan ini.sumber
fork
, membunuh proses induk,setsid
), dan memasukkan anak lain ke dalam sesi baru ini. Namun, ketika proses orang tua (pemimpin sesi baru) meninggal, anak itu tidak menerima SIGHUP, dan terikatinit
sampai akhirnya keluar.setpgid(2)
manpage: Jika suatu sesi memiliki terminal pengendali, dan flag CLOCAL untuk terminal itu tidak diatur, dan terjadi hangup terminal, maka ketua sesi dikirim SIGHUP. Jika pemimpin sesi keluar, maka sinyal SIGHUP juga akan dikirim ke setiap proses dalam kelompok proses latar depan dari terminal pengendali.Jadi apa yang dikatakan poster di atas adalah, anak-anak tidak mati, orang tua membunuh mereka (atau mengirimi mereka sinyal di mana mereka berakhir). Jadi, Anda dapat memiliki apa yang Anda minta, jika Anda memprogram Orang Tua untuk (1) mencatat semua anak-anaknya, dan (2) mengirim sinyal ke semua anak-anaknya.
Inilah yang dilakukan Shell, dan seharusnya itulah yang dilakukan oleh orang tua Anda. Mungkin perlu untuk menangkap sinyal HUP pada orang tua sehingga Anda masih memiliki kontrol yang cukup untuk membunuh anak-anak.
sumber
Saya kehilangan sedikit jawaban yang sedikit berhubungan dengan orang tua yang sekarat: ketika sebuah proses menulis pada sebuah pipa yang tidak ada proses membaca lagi, ia mendapat SIGPIPE. Tindakan standar untuk SIGPIPE adalah penghentian.
Ini memang bisa menyebabkan proses mati. Bahkan, itu adalah cara standar di mana program
yes
mati.Jika saya mengeksekusi
pada sistem saya, jawabannya adalah
dan 141 memang 128 + SIGPIPE:
dari
man 7 signal
.sumber