Entri di POSIX pada "Pembuatan dan Pengiriman Sinyal" di "Dasar Pemikiran:Informasi Umum Antarmuka Sistem" mengatakan
Sinyal yang dihasilkan untuk suatu proses dikirim hanya ke satu utas. Jadi, jika lebih dari satu utas memenuhi syarat untuk menerima sinyal, salah satunya harus dipilih. Pilihan utas diserahkan sepenuhnya pada implementasi baik untuk memungkinkan jangkauan seluas mungkin dari implementasi yang sesuai dan untuk memberikan implementasi kebebasan untuk mengirimkan sinyal ke utas "termudah" jika ada perbedaan dalam kemudahan pengiriman antara utas yang berbeda.
Dari signal(7)
manual pada sistem Linux:
Sinyal dapat dihasilkan (dan dengan demikian tertunda) untuk proses secara keseluruhan (mis., saat dikirim menggunakan
kill(2)
) atau untuk utas tertentu (mis., sinyal tertentu, seperti SIGSEGV dan SIGFPE, yang dihasilkan sebagai konsekuensi dari eksekusi instruksi bahasa mesin tertentu diarahkan oleh utas, sebagai sinyal yang ditargetkan pada utas tertentu menggunakanpthread_kill(3)
). Sinyal yang diarahkan proses dapat dikirim ke salah satu utas yang saat ini tidak memiliki sinyal yang diblokir. Jika lebih dari satu utas memiliki sinyal yang tidak diblokir, maka kernel akan memilih utas arbitrer untuk mengirimkan sinyal.
Dan di pthreads(7)
:
Utas memiliki pengaturan tumpukan sinyal alternatif yang berbeda. Namun, pengaturan tumpukan sinyal alternatif utas baru disalin dari utas yang membuatnya, sehingga utas awalnya berbagi tumpukan sinyal alternatif (diperbaiki di kernel 2.6.16).
Dari pthreads(3)
manual pada sistem OpenBSD (sebagai contoh pendekatan alternatif):
Penangan sinyal biasanya dijalankan pada tumpukan utas yang sedang dieksekusi.
(Saat ini saya tidak mengetahui bagaimana hal ini ditangani ketika banyak utas dijalankan secara bersamaan di mesin multi-prosesor)
Implementasi LinuxThread yang lebih lama dari utas POSIX hanya mengizinkan utas tunggal yang berbeda untuk ditargetkan oleh sinyal. Dari pthreads(7)
pada sistem Linux:
LinuxThreads tidak mendukung gagasan sinyal yang diarahkan proses:sinyal hanya dapat dikirim ke utas tertentu.
Memperluas jawaban yang diterima, ada pandangan yang lebih praktis, yang saya temukan di sini.
Esensinya adalah sebagai berikut:
Penangan sinyal adalah per-proses, tetapi masker sinyal adalah per-utas.
- Dengan demikian, jika kita memasang/mencopot penangan sinyal (dengan signal() atau sigaction()) pada utas apa pun, itu akan memengaruhi semuanya.
- Jika suatu proses mendapat sinyal, penangan akan dieksekusi hanya pada satu utas. Utas ini dipilih secara acak semu di antara mereka, yang topeng sinyalnya menerimanya. Eksperimen saya menunjukkan bahwa itu selalu merupakan utas dengan pid paling sedikit.
- Sinyal yang dikirim ke utas apa pun dianggap sebagai sinyal yang dikirim ke proses utama. Jadi, jika utas mendapat sinyal, sangat mungkin utas lain akan mengeksekusi penangan. Paling baik jika kita melihatnya seolah-olah utas (diidentifikasi oleh
tid
s, id utas) akan dianggap sebagai proses bertopeng (diidentifikasi olehpid
s), dan sinyal dikirim ketid
akan diteruskan kepid
mereka . - Untuk eksekusi penangan sinyal, dalam penyamaran sinyalnya, nomor sinyal yang diberikan disamarkan secara otomatis. Ini untuk mencegah eksekusi penangan sinyal bertumpuk dalam ledakan sinyal. Ini dapat diubah dengan
SA_NODEFER
benderasigaction(...)
panggilan. - (3) dan (4) menghasilkan bahwa dalam kasus ledakan sinyal, sistem mendistribusikan penangan sinyal secara paralel.
- Namun, jika kita telah mengatur sigaction dengan
SA_NODEFER
, selalu utas yang sama akan mendapatkan sinyal dan mereka akan bertumpuk .