《Unix环境高级编程》:同步信号处理

《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+\)

你可能感兴趣的:(《Unix环境高级编程》:同步信号处理)