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 */
}