Proses torunları


20

Bir işlem konteyneri oluşturmaya çalışıyorum. Kapsayıcı diğer programları tetikleyecektir. Örneğin - arka plan görevlerini '&' kullanımıyla başlatan bir bash betiği.

Arkamdaki önemli özellik şudur: konteyneri öldürdüğümde, altında ortaya çıkan her şey öldürülmelidir. Sadece çocukları değil, onların soyundan gelenleri de.

Bu projeye başladığımda yanlışlıkla bir süreci öldürdüğünüzde çocuklarının da otomatik olarak öldürüldüğüne inanıyordum. Aynı yanlış fikri olan insanlardan tavsiye aldım. Bir sinyal yakalamak ve öldürmeyi çocuklara aktarmak mümkün olsa da, burada aradığım şey bu değil.

Ne elde etmek istediğime inanıyorum, çünkü bir xterm'i kapattığınızda, içinde koşan her şey, hiç kimse olmadıkça öldürülür. Buna yetimsiz süreçler de dahildir. Yeniden yaratmak istediğim şey bu.

Aradığım şeyin unix oturumları içerdiğine dair bir fikrim var.

Bir sürecin tüm torunlarını tanımlamanın güvenilir bir yolu olsaydı, onlara rastgele sinyaller göndermek de yararlı olurdu. örneğin SIGUSR1.


Ebeveyn sürecini öldürmek SIGHUPdoğrudan çocuk süreçlerine yol açar. Kapatma sinyalinin varsayılan işleyicisi işlem yürütmeyi iptal eder, böylece varsayılan yol tüm torunları öldürmektir. İşlemler ve işlem grupları hakkında daha fazla bilgi edinin.
alex

Xterm'in kapatılması xterm'de ortaya çıkan her şeyi öldürür çünkü TTY yok edilir. Alt süreçlerin kullanabileceği bir tty oluşturmanın bir yolunu bulursanız, TTY'yi yok edebilir ve aynı şeyi başarabilirsiniz. TTY'yi (nohup & friends) kapatmayan herhangi bir işlem bir SIGHUP alacak.
Patrick

Yanıtlar:


23

Bir sürece sinyal gönderirseniz, o süreç öldürülür. Bir süreci öldürmenin diğer süreçleri de öldürdüğü söylentisinin nasıl başladığını merak ediyorum, özellikle karşı sezgisel görünüyor.

Bununla birlikte, birden fazla süreci öldürmenin yolları vardır. Ancak bir işleme sinyal göndermeyeceksiniz. -1234'e bir sinyal göndererek tüm süreç grubunu öldürebilirsiniz; burada 1234, süreç grubu liderinin PID'si olan PGID'dir (süreç grubu kimliği). Bir boru hattı çalıştırdığınızda , tüm boru hattı bir süreç grubu olarak başlar (uygulamalar bunu setpgidveya öğesini çağırarak değiştirebilir setpgrp).

Arka plandaki ( foo &) işlemlere başladığınızda , bunlar kendi işlem grubundadır. Proses grupları terminale erişimi yönetmek için kullanılır; normalde terminale yalnızca ön plan işlem grubu erişebilir. Arka plan işleri aynı oturumda kalır , ancak bir oturumun tamamını öldürmek veya hatta bir oturumdaki süreç gruplarını veya süreçleri numaralandırmak için hiçbir olanak yoktur, bu da fazla yardımcı olmaz.

Bir terminali kapattığınızda, çekirdek sinyali kontrol terminaliSIGHUP olarak içeren tüm işlemlere gönderir . Bu işlemler bir oturum oluşturur , ancak tüm oturumların kontrol terminali yoktur. Bu nedenle, projeniz için bir olasılık, komut dosyası , ekran vb. Tarafından oluşturulan tüm işlemleri kendi terminalinde başlatmaktır . İçindeki işlemleri öldürmek için terminal emülatör işlemini öldürün (güvenmedikleri varsayılarak ).setsid

İşlemleri kendi kullanıcıları olarak çalıştırarak, başka bir şey yapmayan daha fazla yalıtım sağlayabilirsiniz. Daha sonra tüm işlemleri öldürmek kolaydır: o kullanıcı olarak çalıştırın kill( sistem çağrısı veya yardımcı program ) ve -1'i öldürmek için PID argümanı olarak kullanın, yani “tüm kullanıcının işlemleri”.

Daha fazla yalıtım sağlayabilirsiniz, ancak içerilen işlemleri gerçek bir kapta çalıştırarak çok daha fazla kurulum yapabilirsiniz .


Kendi süreçlerinizi programlıyorsanız, aşağıdaki gibi bir şey kullanabilirsiniz:, prctl(PR_SET_PDEATHSIG, SIGHUP);daha fazla bilgi: man7.org/linux/man-pages/man2/prctl.2.html
Alexis Wilke

Gilles, bundan bahsediyorsunuz - "Bir terminali kapattığınızda, çekirdek SIGHUP sinyalini kontrol terminali olarak sahip olan tüm işlemlere gönderir". Gönderen bu ben terminali düşünüp ediyorum (kabuk) oturumu liderine SIGHUP gönderir kim ileri o oturumdaki tüm süreç gruplarına üzerinde. İkisinden hangisi doğru olurdu?
iruvar

4

Ana kod içinde kill sinyalini yakalayın ve tüm çocukları öldürmesini sağlayın. Örneğin,

#!/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

2

Bir işlemin tüm alt öğelerini tanımlamanın güvenilir bir yolu, pid'in pstree <pid>üst işlem kimliğiniz olduğu komutu kullanmaktır .

pstree Buradaki kılavuz sayfasını okuyun .

Bir işlem grubunun tüm üyelerini işaret etmek için: killpg(<pgrp>, <sig>);
burada pgrp, işlem grubu numarası ve sig ise sinyaldir.

Belirli bir işlem grubundaki çocukları beklemek için: waitpid(-<pgrp>, &status, ...);

Yaptığınız işe bir alternatif, işlem kabınızı yeni bir bash kabuğunda çalıştırmaktır. Komut ile yeni bash kabuğunu oluşturun ve bashişlemlerinizi çalıştırın. Tüm işlemlerin bitmesini istediğinizde, komuttan kabuktan çıkın exit.


Sanırım killpg yapmam gerekeni yapmama izin verecek. Teşekkürler.
Craig Turner

1

kullanım

unshare -fp --kill-child -- yourprogram

Eğer öldürürseniz unshare, ( yourprogramortaya çıkmış olabilecek) tüm çocuk süreçleri öldürülecektir.

Bu artık util-linux ile mümkün 2.32; Bunu akıntıya karşı uyguladım . Kullanıcı ad alanları (çekirdek yapılandırma seçeneği CONFIG_USER_NS=y) veya kök ayrıcalıkları gerektirir. Ayrıca buraya bakınız .


0

rkill gelen komut pslist paketin sinyalini (veya verilen gönderir SIGTERMbelirtilen süreç ve tüm onun soyundan varsayılan olarak):

rkill [-SIG] pid/name...

0

Kabuğun tüm torunlarını öldürmek için başka bir seçenek: jobs -p | xargs -n 1 pkill -P

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.