Selain masalah "terlalu banyak sinyal", sinyal dapat diabaikan secara eksplisit. Dari man 2 signal
:
If the signal signum is delivered to the process, then one of the
following happens:
* If the disposition is set to SIG_IGN, then the signal is ignored.
Sinyal juga dapat diblokir. Dari man 7 signal
;
A signal may be blocked, which means that it will not be delivered
until it is later unblocked. Between the time when it is generated
and when it is delivered a signal is said to be pending.
Kedua set sinyal yang diblokir dan diabaikan diwarisi oleh proses anak, sehingga dapat terjadi bahwa proses induk aplikasi Anda mengabaikan atau memblokir salah satu sinyal ini.
Apa yang terjadi ketika beberapa sinyal dikirim sebelum proses selesai menangani yang sebelumnya? Itu tergantung pada OS. Halaman yang signal(2)
terhubung di atas membahasnya:
- Sistem V akan mengatur ulang disposisi sinyal ke default. Lebih buruk lagi, pengiriman cepat dari beberapa sinyal akan menghasilkan panggilan rekursif (?).
- BSD akan secara otomatis memblokir sinyal sampai pawang selesai.
- Di Linux, ini tergantung pada flag kompilasi yang diatur untuk GNU
libc
, tapi saya mengharapkan perilaku BSD.
signal(2)
tegas menyarankan agar Anda menghindari kebingungan ini dengan menggunakannyasigaction(2)
.Anda tidak dapat mempercayai bahwa setiap sinyal yang dikirim akan dikirimkan. Sebagai contoh, kernel linux "menyatukan" SIGCHLD jika suatu proses membutuhkan waktu lama dalam menangani SIGCHLD dari proses anak yang sudah keluar.
Untuk menjawab bagian lain dari pertanyaan Anda, sinyal "antri" di dalam kernel jika sejumlah sinyal berbeda datang terlalu pendek.
Anda harus menggunakan
sigaction()
untuk mengatur pengendali sinyal dengansa_sigaction
anggotasiginfo_t
, mengatursa_mask
anggotasiginfo_t
argumen dengan hati-hati. Saya pikir ini berarti menutupi semua sinyal "asynch" setidaknya. Menurut halaman manual untuk Linuxsigaction()
, Anda juga akan menutupi sinyal yang sedang ditangani. Saya pikir Anda harus mengatursa_flags
anggota untuk SA_SIGINFO, tetapi saya tidak ingat mengapa saya memiliki takhayul ini. Saya percaya ini akan membuat proses Anda penangan sinyal yang tetap diatur tanpa kondisi balapan, dan yang tidak terganggu oleh sebagian besar sinyal lainnya.Tulis fungsi penangan sinyal Anda dengan sangat, sangat hati-hati. Pada dasarnya hanya mengatur variabel global untuk menunjukkan bahwa sinyal tertangkap, dan memiliki sisa proses berurusan dengan tindakan yang diinginkan untuk sinyal itu. Sinyal akan ditutup untuk paling sedikit waktu seperti itu.
Selain itu, Anda harus menguji kode penanganan sinyal dengan sangat teliti. Masukkan ke dalam proses pengujian kecil dan kirim sebanyak mungkin sinyal SIGUSR1 dan SIGUSR2, mungkin dari 2 atau 3 program pengiriman sinyal tujuan khusus. Campurkan beberapa sinyal lain juga, setelah Anda yakin bahwa kode Anda dapat menangani SIGUSR1 dan SIGUSR2 dengan cepat dan benar. Persiapkan diri Anda untuk debugging yang sulit.
Jika Anda menggunakan linux dan hanya linux, Anda mungkin berpikir untuk menggunakan
signalfd()
untuk membuat deskriptor file yang Anda bisaselect()
atau polling untuk menerima sinyal-sinyal itu. Menggunakansignalfd()
mungkin membuat proses debug lebih mudah.sumber
Sinyal dijamin akan dikirimkan, dalam arti jika suatu proses berhasil memanggil
kill
, maka target akan menerima sinyal. Ini asinkron: pengirim tidak memiliki cara untuk mengetahui kapan sinyal diterima atau diproses. Namun, ini tidak menjamin bahwa sinyal akan dikirimkan. Target bisa mati sebelum dapat memproses sinyal. Jika target mengabaikan sinyal pada saat itu disampaikan, sinyal tidak akan berpengaruh. Jika target menerima beberapa instance dari nomor sinyal yang sama sebelum dapat memprosesnya, sinyal dapat (dan biasanya) digabung: jika Anda mengirim sinyal yang sama dua kali ke suatu proses, Anda tidak dapat mengetahui apakah proses akan menerima sinyal sekali atau dua kali. Sinyal sebagian besar dirancang untuk mematikan proses atau sebagai cara untuk membuat proses memperhatikan, mereka tidak dirancang untuk komunikasi seperti itu.Jika Anda membutuhkan pengiriman yang andal maka Anda memerlukan mekanisme komunikasi yang berbeda. Ada dua mekanisme komunikasi utama antara proses: pipa memungkinkan komunikasi searah; sebuah soket memungkinkan komunikasi dua arah dan beberapa sambungan ke server yang sama. Jika Anda memerlukan target untuk memproses sebanyak mungkin notifikasi yang Anda kirim, kirim byte melalui pipa.
sumber
Kernel bebas untuk menyatukan sinyal standar jika lebih dari satu dikirimkan saat diblokir. Sinyal real-time tidak cacat sama.
Dari halaman manual signal (7) :
Coba gunakan sinyal dengan angka dalam rentang SIGRTMIN ke SIGRTMAX.
sumber
ulimit -i
menunjukkan nilai ini sebagai 63432 di Ubuntu 18,04.