您的位置:首页 > 运维架构 > Linux

Linux Advance--同步信号处理

2015-11-22 14:08 766 查看
下面讲一个同步信号处理的程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <signal.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 err, signo;

while(1) {
err = sigwait(&mask, &signo);
if (err != 0) {
printf("sigwait failed: %s\n", strerror(err));
exit(1);
}
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()
{
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) {
printf("SIG_BLOCK error: %s\n", strerror(err));
exit(1);
}

err = pthread_create(&tid, 0, thr_fn, 0);
if (err != 0) {
printf("can't create thread: %s\n", strerror(err));
exit(1);
}

pthread_mutex_lock(&lock);
while (quitflag == 0)
pthread_cond_wait(&wait, &lock);
pthread_mutex_unlock(&lock);

quitflag = 0;

if (sigprocmask(SIG_SETMASK, &oldmask, 0) < 0) {
printf("SIG_SETMASK error: %s\n", strerror(err));
exit(1);
}
exit(0);
}


这里并不让信号处理程序中断主控线程,而是由专门的独立控制线程进行信号处理。改动 quitflag 的值是在互斥量的保护下进行的,这样主控线程不会在调用 pthread_cond_signal 时错失唤醒调用。在主控线程中使用相同的互斥量来检查标志的值,并且原子地释放互斥量,等待条件的发生。

注意在主线程开始时阻塞 SIGINT 和 SIGQUIT,当创建线程进行信号处理时,新建线程继承了现有的信号屏蔽字。因为 sigwait 会解除信号的阻塞状态,所以只有一个线程可以用于信号的接收。这使得对主线程进行编码时不必担心来自这些信号的中断。

下面是在终端下运行的效果:



下面是终端下发送 kill 信号时的效果:

(第一个终端运行程序,处于等待状态)



(第二个终端发送 kill 信号,首先找到程序的进程号,然后发信号)



(第一个终端的结果,三个中断信号和一个终止信号)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: