GNU/Linux >> Belajar Linux >  >> Linux

Penanganan sinyal dengan banyak utas di Linux

pthreads(7) menjelaskan bahwa POSIX.1 membutuhkan semua utas dalam atribut berbagi proses, termasuk:

  • disposisi sinyal

POSIX.1 juga membutuhkan beberapa atribut untuk berbeda untuk setiap utas, termasuk:

  • topeng sinyal (pthread_sigmask(3) )

  • tumpukan sinyal alternatif (sigaltstack(2) )

complete_signal kernel Linux rutin memiliki blok kode berikut -- komentarnya cukup berguna:

/*
 * Now find a thread we can wake up to take the signal off the queue.
 *
 * If the main thread wants the signal, it gets first crack.
 * Probably the least surprising to the average bear.
 */
if (wants_signal(sig, p))
        t = p;
else if (!group || thread_group_empty(p))
        /*
         * There is just one thread and it does not need to be woken.
         * It will dequeue unblocked signals before it runs again.
         */
        return;
else {
        /*
         * Otherwise try to find a suitable thread.
         */
        t = signal->curr_target;
        while (!wants_signal(sig, t)) {
                t = next_thread(t);
                if (t == signal->curr_target)
                        /*
                         * No thread needs to be woken.
                         * Any eligible threads will see
                         * the signal in the queue soon.
                         */
                        return;
        }
        signal->curr_target = t;
}

/*
 * Found a killable thread.  If the signal will be fatal,
 * then start taking the whole group down immediately.
 */
if (sig_fatal(p, sig) &&
    !(signal->flags & SIGNAL_GROUP_EXIT) &&
    !sigismember(&t->real_blocked, sig) &&
    (sig == SIGKILL || !p->ptrace)) {
        /*
         * This signal will be fatal to the whole group.
         */

Jadi, Anda melihat bahwa Anda bertanggung jawab atas pengiriman sinyal:

Jika proses Anda telah menyetel disposisi sinyal ke SIG_IGN atau SIG_DFL , maka sinyal diabaikan (atau default -- bunuh, core, atau abaikan) untuk semua utas.

Jika proses Anda telah menyetel disposisi sinyal ke rutin penangan tertentu, maka Anda dapat mengontrol utas mana yang akan menerima sinyal dengan memanipulasi masker sinyal utas tertentu menggunakan pthread_sigmask(3) . Anda dapat menominasikan satu utas untuk mengelola semuanya, atau membuat satu utas per sinyal, atau campuran apa pun dari opsi ini untuk sinyal tertentu, atau Anda mengandalkan perilaku default kernel Linux saat ini dalam mengirimkan sinyal ke utas utama.

Namun, beberapa sinyal khusus menurut signal(7) halaman manual:

Sinyal dapat dihasilkan (dan dengan demikian tertunda) untuk suatu proses secara keseluruhan (misalnya, saat dikirim menggunakan kill(2)) atau untuk utas tertentu (misalnya, sinyal tertentu, seperti SIGSEGV dan SIGFPE, dihasilkan sebagai konsekuensi dari eksekusi instruksi bahasa mesin tertentu diarahkan oleh utas, seperti halnya sinyal yang ditargetkan pada utas tertentu menggunakan pthread_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.


Ini sedikit bernuansa, berdasarkan versi kernel Linux mana yang Anda gunakan.

Dengan asumsi 2,6 utas posix, dan jika Anda berbicara tentang OS yang mengirimkan SIGTERM atau SIGHUP, sinyal dikirim ke proses, yang diterima oleh dan ditangani oleh utas root. Dengan menggunakan utas POSIX, Anda juga dapat mengirim SIGTERM ke masing-masing utas, tetapi saya menduga Anda bertanya tentang apa yang terjadi ketika OS mengirimkan sinyal ke proses.

Di 2.6, SIGTERM akan menyebabkan utas anak keluar "dengan bersih", sedangkan 2.4, utas anak dibiarkan dalam keadaan tak tentu.


Linux
  1. Linux – Mengatur Proses Menjalankan Afinitas Dengan Taskset Gagal?

  2. Cara Membuat Thread di Linux (Dengan Program Contoh C)

  3. Apakah utas kernel Linux benar-benar proses kernel?

  1. Cara Mengelola Beberapa Versi Python Dengan Pyenv Di Linux

  2. Perintah JQ di Linux dengan Contoh

  3. Apa yang terjadi pada proses Linux multithreaded jika mendapat sinyal?

  1. Bagaimana memberi nama utas di Linux?

  2. Penanganan sinyal UNIX/Linux:SIGEV_THREAD

  3. Apakah fopen() fungsi thread safe di Linux?