《Unix环境高级编程》这本书附带了许多短小精美的小程序,我在阅读此书的时候,将书上的代码按照自己的理解重写了一遍(大部分是抄书上的),加深一下自己的理解(纯看书太困了,呵呵)。此例子在Ubuntu10.04上测试通过。
程序简介:在多线程程序中等侍信号设置标志,从而让主程序退出。唯一可运行的控制线程应该是主线程和信号处理程序,所以阻塞信号足以避免错失标志的修改。另外在线程中,需要使用互斥量来保护标志。以下这个程序演示了这方面的内容。
//《APUE》程序12-6:同步信号处理 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <pthread.h> int quitflag; sigset_t mask; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t wait = PTHREAD_COND_INITIALIZER; void *thr_fn(void *arg) { int signo; while(1) { //设置阻塞信号集 sigwait(&mask, &signo); 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) { sigset_t oldmask; pthread_t tid; sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); pthread_sigmask(SIG_BLOCK, &mask, &oldmask); pthread_create(&tid, NULL, thr_fn, 0); /* 经典的UNIX条件锁三步曲: 1。使用pthread_cond_wait前要先加锁 2。pthread_cond_wait内部会解锁,然后等待条件变量被其它线程激活 3。pthread_cond_wait被激活后会再自动加锁 (所以还要我们视情况而决定是否手动解锁) */ pthread_mutex_lock(&lock); while( 0 == quitflag ) pthread_cond_wait(&wait, &lock); pthread_mutex_unlock(&lock); //收到退出信号,但现在这个信号是阻塞的 quitflag = 0; //重置阻塞信号集(让程序退出) sigprocmask(SIG_SETMASK, &oldmask, NULL); return 0; }
运行示例(红色字体的为输入):
qch@ubuntu:~/code$gcc temp.c -lpthread -o temp
qch@ubuntu:~/code$ ./temp
^C #输入中断字符(ctrl+C)
interrupt
^C #输入中断字符(ctrl+C)
interrupt
^C #输入中断字符(ctrl+C)
interrupt
^\ #输入退出字符(ctrl+\)