GNU/Linux >> Belajar Linux >  >> Linux

Utas mana yang menangani sinyal?

Baca dengan cermat signal(7) &pthread(7) &pthread_kill(3) &sigprocmask(2) &pthread_sigmask(3) - yang dapat Anda gunakan (untuk memblokir SIGINT di utas yang tidak diinginkan). Baca juga tutorial pthread.

Hindari menggunakan sinyal untuk berkomunikasi atau menyinkronkan antar utas. Pertimbangkan mis. mutex (pthread_mutex_lock dll...) dan variabel kondisi (pthread_cond_wait dll...).

Jika salah satu utas menjalankan loop peristiwa (misalnya di sekitar poll(2)...) pertimbangkan untuk menggunakan signalfd(2).


Jika Anda mengirim sinyal ke suatu proses, utas mana dalam proses yang akan menangani sinyal ini tidak ditentukan.

Menurut pthread(7) :

POSIX.1 juga mengharuskan utas berbagi rentang atribut lain (yaitu, atribut ini mencakup seluruh proses, bukan per utas):
...
- disposisi sinyal
...

POSIX.1 membedakan pengertian sinyal yang diarahkan ke proses secara keseluruhan dan sinyal yang diarahkan ke masing-masing utas. Menurut POSIX.1, sinyal yang diarahkan proses (dikirim menggunakan kill(2) , misalnya) harus ditangani oleh satu, sewenang-wenang utas yang dipilih dalam proses.

Jika Anda menginginkan utas khusus dalam proses Anda untuk menangani beberapa sinyal, berikut adalah contoh dari pthread_sigmask(3) menunjukkan cara melakukannya:

Program di bawah memblokir beberapa sinyal di utas utama, lalu membuat utas khusus untuk mengambil sinyal tersebut melalui sigwait(3). Sesi shell berikut menunjukkan penggunaannya:

$ ./a.out &
[1] 5423
$ kill -QUIT %1
Signal handling thread got signal 3
$ kill -USR1 %1
Signal handling thread got signal 10
$ kill -TERM %1
[1]+  Terminated              ./a.out

Sumber program

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

/* Simple error handling functions */

#define handle_error_en(en, msg) \
        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void *
sig_thread(void *arg)
{
    sigset_t *set = arg;
    int s, sig;

   for (;;) {
        s = sigwait(set, &sig);
        if (s != 0)
            handle_error_en(s, "sigwait");
        printf("Signal handling thread got signal %d\n", sig);
    }
}

int
main(int argc, char *argv[])
{
    pthread_t thread;
    sigset_t set;
    int s;

   /* Block SIGQUIT and SIGUSR1; other threads created by main()
       will inherit a copy of the signal mask. */

   sigemptyset(&set);
    sigaddset(&set, SIGQUIT);
    sigaddset(&set, SIGUSR1);
    s = pthread_sigmask(SIG_BLOCK, &set, NULL);
    if (s != 0)
        handle_error_en(s, "pthread_sigmask");

   s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);
    if (s != 0)
        handle_error_en(s, "pthread_create");

   /* Main thread carries on to create other threads and/or do
       other work */

   pause();            /* Dummy pause so we can test program */
}

Linux
  1. Bagaimana Memberi Sinyal Akhir Dari Input Stdin?

  2. Sistem File Mana Yang Harus Dicadangkan Yang Terbaik??

  3. Perbedaan antara Cari/di mana/yang mana?

  1. Bagaimana cara bergabung dengan utas yang menggantung di pemblokiran IO?

  2. Melacak asal sinyal UNIX?

  3. Penanganan sinyal dengan banyak utas di Linux

  1. Perintah terminal Linux mana yang paling sering Anda gunakan?

  2. Bagaimana cara mengatur nama utas di Linux pthreads?

  3. Bagaimana cara mengubah ukuran font di Dwarf-fortress?