Mengapa saya tidak bisa membunuh proses SIGSTOP dengan SIGTERM, dan di mana sinyal yang tertunda disimpan?

24

Saya menggunakan stretch Debian (systemd). Saya sedang menjalankan daemon rsyslog di foreground menggunakan /usr/sbin/rsyslogd -n dan saya melakukan Ctrl+ Zuntuk menghentikannya. Keadaan proses berubah menjadi Tl(berhenti, berulir). Aku mengeluarkan beberapa perintah ke proses, dan keadaan proses adalah sama: . Setelah saya melakukan , itu mati. Saya punya 3 pertanyaan.kill -15 <pid>Tlfg

  • Mengapa SIGSTOPproses the -ed tidak merespons SIGTERM? Mengapa kernel menyimpannya dalam kondisi yang sama?
  • Mengapa itu terbunuh saat menerima SIGCONTsinyal?
  • Jika itu karena SIGTERMsinyal sebelumnya , di mana ia disimpan sampai proses dilanjutkan?
tidak
sumber

Jawaban:

41

SIGSTOPdan SIGKILLmerupakan dua sinyal yang tidak dapat ditangkap dan ditangani oleh suatu proses. SIGTSTPseperti SIGSTOPkecuali bahwa itu dapat ditangkap dan ditangani.

The SIGSTOPdan SIGTSTPsinyal menghentikan proses di jalurnya, siap SIGCONT. Ketika Anda mengirim proses itu SIGTERM, proses tidak berjalan dan sehingga tidak dapat menjalankan kode untuk keluar.

(Ada juga SIGTTINdan SIGTTOU, yang merupakan sinyal yang dihasilkan oleh lapisan TTY ketika pekerjaan latar belakang mencoba membaca atau menulis ke terminal. Mereka dapat ditangkap tetapi sebaliknya akan menghentikan (menunda) proses, sama seperti SIGTSTP. Tapi saya sekarang akan untuk mengabaikan keduanya untuk sisa jawaban ini.)

Anda CtrlZmengirimkan proses a SIGTSTP, yang tampaknya tidak ditangani secara khusus dengan cara apa pun oleh rsyslogd, jadi itu hanya menunda proses yang tertunda SIGCONTatau SIGKILL.

Solusi di sini adalah mengirim SIGCONTsetelah Anda SIGTERMsehingga proses dapat menerima dan menangani sinyal.

Contoh:

sleep 999 &

# Assume we got PID 456 for this process
kill -TSTP 456    # Suspend the process (nicely)
kill -TERM 456    # Terminate the process (nicely). Nothing happens
kill -CONT 456    # Continue the process so it can exit cleanly

Dokumentasi untuk Perpustakaan C GNU menjelaskan ini dengan cukup baik, saya pikir (sorotan saya):

Ketika suatu proses dihentikan, tidak ada lagi sinyal yang dapat dikirim sampai diteruskan , kecuali SIGKILLsinyal dan (jelas) SIGCONTsinyal. Sinyal ditandai sebagai tertunda, tetapi tidak dikirimkan sampai proses dilanjutkan. The SIGKILLsinyal selalu menyebabkan penghentian proses dan tidak dapat diblokir, ditangani atau diabaikan. Anda dapat mengabaikannya SIGCONT, tetapi hal itu selalu menyebabkan proses dilanjutkan jika dihentikan. Mengirim SIGCONTsinyal ke suatu proses menyebabkan sinyal berhenti yang tertunda untuk proses tersebut akan dibuang. Demikian juga, setiap SIGCONTsinyal yang tertunda untuk suatu proses dibuang ketika menerima sinyal berhenti

roaima
sumber
1
@ tidak. jawaban diperluas, tetapi pada dasarnya, "ya; itu menangani kill -15Anda sudah mengirim".
roaima
2
@nohup ya, sesuai dengan dokumentasi: « Ketika suatu proses dihentikan, tidak ada lagi sinyal yang dapat dikirimkan sampai diteruskan ... Sinyal ditandai sebagai tertunda, tetapi tidak dikirimkan sampai proses dilanjutkan. »
roaima
1
Lihat juga SIGTTIN dan SIGTTOU yang juga menghentikan proses
Stéphane Chazelas
1
@ StéphaneChazelas poin bagus. Saya telah menambahkan menyebutkan ini tetapi mengabaikannya. Silakan diedit sesuai keinginan Anda.
roaima
2
@coteyr Saya tidak setuju: SIGKILLmencegah aplikasi membersihkan, jadi menggunakan SIGTERMlebih disukai dalam banyak (sebagian besar) kasus.
roaima
9

SIGTERMsama seperti sinyal lainnya yang dapat ditangkap oleh suatu proses. Menerima sinyal hanya akan membuat proses melompat ke rutinitas pengendali sinyal khusus. Untuk SIGTERMtindakan standar akan menghentikan proses, tetapi misalnya editor mungkin ingin menangkap sinyal sehingga dapat menyimpan draft salinan semua file yang terbuka sebelum mati. Jika proses dihentikan, itu tidak dapat menjalankan penangan sinyal, tetapi sinyal akan tetap tertunda sampai proses berlanjut. Perhatikan bahwa jumlah sinyal yang dikirim biasanya tidak akan disimpan.

Secara teori, sistem dapat mengetahui apakah proses tersebut memiliki pengatur sinyal yang diinstal SIGTERM, dan segera menghentikannya jika tidak. Tetapi (sesuai komentar Gilles ') POSIX menuntut agar sinyal akan ditunda hingga proses dilanjutkan SIGCONT.

ilkkachu
sumber
4
Maaf, komentar saya sebelumnya salah. Ketika suatu proses dihentikan, tidak ada sinyal yang dikirimkan kecuali SIGKILL dan SIGCONT. Bahkan jika sinyal memiliki aksi standarnya yaitu untuk mematikan proses, ini ditunda sampai proses dilanjutkan oleh SIGCONT. POSIX mengamanatkan perilaku ini.
Gilles 'SO- stop being evil'