#include <signal.h>
int pthread_sigmask(int how, const sigset_t *restrict set,
sigset_t *restrict oset);
Returns: 0 if OK, error number on failure
說明:
1. 每個(gè)線程都有自己獨(dú)立的信號(hào)屏蔽,但卻共享進(jìn)程的信號(hào)處理。這意味著在一個(gè)線程中改變信號(hào)處理,會(huì)影響到其他線程。
2. 創(chuàng)建新線程時(shí),新線程繼承主線程的當(dāng)前信號(hào)屏蔽。
3. 當(dāng)信號(hào)是由于硬件錯(cuò)誤或者定時(shí)器溢出而引起時(shí),信號(hào)被發(fā)往引起該信號(hào)的線程;其他情況下,信號(hào)送往進(jìn)程的隨意一個(gè)線程。
4. pthread_sigmask 是多線程下的信號(hào)屏蔽設(shè)置函數(shù),參數(shù)與 sigprocmask 類似。后者在多線程環(huán)境下,行為未定義。
#include <signal.h>
int sigwait(const sigset_t *restrict set, int *restrict signop);
Returns: 0 if OK, error number on failure
說明:
1. 使用 sigwait 等待特定信號(hào)前,首先要屏蔽該信號(hào),進(jìn)入sigwait 后會(huì)自動(dòng)解除阻塞,sigwait 返回前,重新恢復(fù)信號(hào)屏蔽。
2. sigwait 提供了異步信號(hào)的同步處理方式—— 可以在每個(gè)線程中屏蔽信號(hào),而選特定的一個(gè)或多個(gè)線程去處理信號(hào)。在線程的上下文中處理信號(hào),而不在傳統(tǒng)的打斷線程執(zhí)行的信號(hào)句柄。
3. 當(dāng)有多個(gè)線程都調(diào)用 sigwait 等待同一信號(hào)時(shí),信號(hào)到達(dá)時(shí),只有一個(gè)線程的 sigwait 會(huì)返回。另外當(dāng)信號(hào)句柄與sigwait 同時(shí)存在時(shí),信號(hào)的處理取決于實(shí)現(xiàn),但兩者只能取其一。
4. APUEv2 給出的例子如下:
#include "apue.h"
#include <pthread.h>
int quitflag; /* set nonzero by thread */
sigset_t mask;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t wait = PTHREAD_COND_INITIALIZER;
void *
thr_fn(void *arg)
{
int err, signo;
for (;;) {
err = sigwait(&mask, &signo);
if (err != 0)
err_exit(err, "sigwait failed");
switch (signo) {
case SIGINT:
printf("\ninterrupt\n");
break;
case SIGQUIT:
pthread_mutex_lock(&lock);
quitflag = 1;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&wait);
return(0);
default:
printf("unexpected signal %d\n", signo);
exit(1);
}
}
}
int
main(void)
{
int err;
sigset_t oldmask;
pthread_t tid;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
if ((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)
err_exit(err, "SIG_BLOCK error");
err = pthread_create(&tid, NULL, thr_fn, 0);
if (err != 0)
err_exit(err, "can't create thread");
pthread_mutex_lock(&lock);
while (quitflag == 0)
pthread_cond_wait(&wait, &lock);
pthread_mutex_unlock(&lock);
/* SIGQUIT has been caught and is now blocked; do whatever */
quitflag = 0;
/* reset signal mask which unblocks SIGQUIT */
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
exit(0);
}
#include <signal.h>
int pthread_kill(pthread_t thread, int signo);
Returns: 0 if OK, error number on failure
說明:
1. 該函數(shù)用來向線程發(fā)送信號(hào)。
2. 如果信號(hào)默認(rèn)會(huì)終止進(jìn)程,則向線程發(fā)送該信號(hào)會(huì)終止線程所在的進(jìn)程。
3. 定時(shí)器(alarm_timer)是進(jìn)程資源,進(jìn)程的所有線程共享同一套定時(shí)器。所以在線程中同時(shí)設(shè)置定時(shí)器會(huì)相互干擾。