#include <signal.h>Returns: 0 if OK, error number on failure
int pthread_sigmask(int how, const sigset_t *restrict set,
sigset_t *restrict oset);
说明:
1. 每个线程都有自己独立的信号屏蔽,但却共享进程的信号处理。这意味着在一个线程中改变信号处理,会影响到其他线程。
2. 创建新线程时,新线程继承主线程的当前信号屏蔽。
3. 当信号是由于硬件错误或者定时器溢出而引起时,信号被发往引起该信号的线程;其他情况下,信号送往进程的随意一个线程。
4. pthread_sigmask 是多线程下的信号屏蔽设置函数,参数与 sigprocmask 类似。后者在多线程环境下,行为未定义。
#include <signal.h>Returns: 0 if OK, error number on failure
int sigwait(const sigset_t *restrict set, int *restrict signop);
说明:
1. 使用 sigwait 等待特定信号前,首先要屏蔽该信号,进入sigwait 后会自动解除阻塞,sigwait 返回前,重新恢复信号屏蔽。
2. sigwait 提供了异步信号的同步处理方式—— 可以在每个线程中屏蔽信号,而选特定的一个或多个线程去处理信号。在线程的上下文中处理信号,而不在传统的打断线程执行的信号句柄。
3. 当有多个线程都调用 sigwait 等待同一信号时,信号到达时,只有一个线程的 sigwait 会返回。另外当信号句柄与sigwait 同时存在时,信号的处理取决于实现,但两者只能取其一。
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. 该函数用来向线程发送信号。
2. 如果信号默认会终止进程,则向线程发送该信号会终止线程所在的进程。
3. 定时器(alarm_timer)是进程资源,进程的所有线程共享同一套定时器。所以在线程中同时设置定时器会相互干扰。