Keturunan proses

20

Saya mencoba membangun sebuah wadah proses. Kontainer akan memicu program lain. Misalnya - skrip bash yang meluncurkan menjalankan tugas latar belakang dengan penggunaan '&'.

Fitur penting yang saya kejar adalah ini: ketika saya membunuh wadah itu, semua yang telah dihasilkan di bawahnya harus dibunuh. Bukan hanya mengarahkan anak-anak, tetapi juga keturunan mereka.

Ketika saya memulai proyek ini, saya secara keliru percaya bahwa ketika Anda membunuh suatu proses, anak-anaknya juga terbunuh secara otomatis. Saya telah meminta saran dari orang-orang yang memiliki gagasan salah yang sama. Meskipun mungkin untuk menangkap sinyal dan meneruskan pembunuhan kepada anak-anak, bukan itu yang saya cari di sini.

Saya percaya apa yang ingin saya capai, karena ketika Anda menutup xterm, apa pun yang berjalan di dalamnya terbunuh kecuali itu tidak ada. Ini termasuk proses yatim. Itulah yang saya cari untuk diciptakan kembali.

Saya punya ide bahwa apa yang saya cari melibatkan sesi unix.

Jika ada cara yang dapat diandalkan untuk mengidentifikasi semua keturunan suatu proses, akan sangat berguna untuk dapat mengirimi mereka sinyal sewenang-wenang juga. misalnya SIGUSR1.

Craig Turner
sumber
Nah, membunuh proses orang tua mengirim SIGHUPke proses anak langsung itu. Penangan default dari sinyal hang membatalkan proses eksekusi, sehingga rute default adalah untuk membunuh semua keturunan. Baca lebih lanjut tentang proses dan kelompok proses.
alex
Menutup xterm membunuh semua yang muncul dalam xterm karena TTY dihancurkan. Jika Anda dapat menemukan cara untuk membuat tty yang dapat digunakan proses anak, Anda kemudian dapat menghancurkan TTY dan mencapai hal yang sama. Setiap proses yang tidak menutup TTY (nohup & teman-teman) akan mendapatkan SIGHUP.
Patrick

Jawaban:

23

Jika Anda mengirim sinyal ke suatu proses, proses itu terbunuh. Saya bertanya-tanya bagaimana rumor bahwa membunuh suatu proses juga membunuh proses lain dimulai, tampaknya sangat kontra-intuitif.

Namun, ada cara untuk membunuh lebih dari satu proses. Tetapi Anda tidak akan mengirim sinyal ke satu proses. Anda dapat membunuh seluruh grup proses dengan mengirimkan sinyal ke -1234 di mana 1234 adalah PGID (ID grup proses), yang merupakan PID dari pemimpin grup proses. Saat Anda menjalankan pipa , seluruh pipa dimulai sebagai grup proses (aplikasi dapat mengubahnya dengan menelepon setpgidatau setpgrp).

Saat Anda memulai proses di latar belakang ( foo &), mereka berada di grup proses mereka sendiri. Grup proses digunakan untuk mengelola akses ke terminal; biasanya hanya grup proses latar depan yang memiliki akses ke terminal. Pekerjaan latar belakang tetap dalam sesi yang sama , tetapi tidak ada fasilitas untuk membunuh seluruh sesi atau bahkan untuk menghitung kelompok proses atau proses dalam satu sesi, sehingga tidak banyak membantu.

Ketika Anda menutup terminal, kernel mengirimkan sinyal SIGHUPke semua proses yang menjadikannya sebagai terminal pengendali mereka . Proses-proses ini membentuk suatu sesi , tetapi tidak semua sesi memiliki terminal pengendali. Untuk proyek Anda, satu kemungkinan karena itu untuk memulai semua proses di terminal mereka sendiri, dibuat oleh skrip , layar , dll. Bunuh proses emulator terminal untuk membunuh proses yang terkandung (dengan asumsi mereka belum memisahkan diri dengan setsid).

Anda dapat memberikan lebih banyak isolasi dengan menjalankan proses sebagai pengguna mereka sendiri, yang tidak melakukan hal lain. Maka mudah untuk membunuh semua proses: jalankan kill( panggilan sistem atau utilitas ) sebagai pengguna itu dan gunakan -1 sebagai argumen PID untuk mematikan, yang berarti "semua proses pengguna itu".

Anda dapat memberikan lebih banyak isolasi, tetapi dengan setup jauh lebih dengan menjalankan proses yang terkandung dalam sebenarnya kontainer .

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Jika Anda memprogram proses Anda sendiri, maka Anda dapat menggunakan sesuatu seperti :,prctl(PR_SET_PDEATHSIG, SIGHUP); info lebih lanjut: man7.org/linux/man-pages/man2/prctl.2.html
Alexis Wilke
Gilles, Anda menyebutkan ini - "Ketika Anda menutup terminal, kernel mengirimkan sinyal SIGHUP ke semua proses yang memilikinya sebagai terminal pengendali mereka". Dari sini saya menduga terminal mengirimkan SIGHUP ke ketua sesi (shell) yang meneruskannya ke semua grup proses dalam sesi. Yang mana dari keduanya yang benar?
iruvar
4

Di dalam skrip induk menjebak sinyal membunuh dan membuatnya membunuh semua anak. Sebagai contoh,

#!/bin/bash
# kill the parent and children together
trap "kill 0" EXIT
# create all the children
for n in $(seq 1 100)
do
    ( echo "begin $n"; sleep 60; echo "end $n" ) &
done
# wait for the children to complete
wait
Andrew Gilmartin
sumber
2

Cara yang dapat diandalkan untuk mengidentifikasi semua keturunan suatu proses adalah dengan menggunakan perintah di pstree <pid>mana pid adalah id proses induk Anda.

Baca halaman manual di pstree sini .

Untuk memberi sinyal semua anggota grup proses: di killpg(<pgrp>, <sig>);
mana pgrp adalah nomor grup proses dan sig adalah sinyal.

Untuk menunggu anak-anak dalam kelompok proses tertentu: waitpid(-<pgrp>, &status, ...);

Alternatif untuk apa yang Anda lakukan adalah menjalankan wadah proses Anda di bash shell baru. Buat bash shell baru dengan perintah bashlalu jalankan proses Anda. Saat Anda ingin semua proses diakhiri, keluar dari shell dengan perintah exit.

Chris Ting
sumber
Saya pikir killpg akan memungkinkan saya untuk melakukan apa yang perlu saya lakukan. Terima kasih.
Craig Turner
1

Menggunakan

unshare -fp --kill-child -- yourprogram

Jika Anda membunuh unshare, semua proses anak (yang yourprogrammungkin telah melahirkan) akan dibunuh.

Ini sekarang dimungkinkan dengan util-linux 2.32; Saya menerapkan hulu ini . Ini membutuhkan ruang nama pengguna (opsi konfigurasi kernel CONFIG_USER_NS=y) atau hak root. Lihat juga di sini .

nh2
sumber
0

perintah rkill dari paket pslist mengirimkan sinyal yang diberikan (atau SIGTERMsecara default) ke proses yang ditentukan dan semua turunannya:

rkill [-SIG] pid/name...
Onlyjob
sumber
0

Opsi lain untuk membunuh semua keturunan shell: jobs -p | xargs -n 1 pkill -P

Doug Fawley
sumber