Linux Advance--同步信号处理
2015-11-22 14:08
766 查看
下面讲一个同步信号处理的程序:
这里并不让信号处理程序中断主控线程,而是由专门的独立控制线程进行信号处理。改动 quitflag 的值是在互斥量的保护下进行的,这样主控线程不会在调用 pthread_cond_signal 时错失唤醒调用。在主控线程中使用相同的互斥量来检查标志的值,并且原子地释放互斥量,等待条件的发生。
注意在主线程开始时阻塞 SIGINT 和 SIGQUIT,当创建线程进行信号处理时,新建线程继承了现有的信号屏蔽字。因为 sigwait 会解除信号的阻塞状态,所以只有一个线程可以用于信号的接收。这使得对主线程进行编码时不必担心来自这些信号的中断。
下面是在终端下运行的效果:
下面是终端下发送 kill 信号时的效果:
(第一个终端运行程序,处于等待状态)
(第二个终端发送 kill 信号,首先找到程序的进程号,然后发信号)
(第一个终端的结果,三个中断信号和一个终止信号)
#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 信号,首先找到程序的进程号,然后发信号)
(第一个终端的结果,三个中断信号和一个终止信号)
相关文章推荐
- 在centos中编译putty时提示找不到gtk库的解决办法
- linux下配置Qt5 开发环境
- 为centos安装xfce4桌面环境的命令
- 为centos添加额外的源
- linux常用命令
- linux 775和777权限有什么区别
- linux su和sudo命令的区别
- VMware中安装RHEL 7.1后出现锁屏的解决方法
- linux中 find命令的总结
- ffmpeg 在linux下编译
- linux日常管理-防火墙selinux
- 源码安装MySQL5.5.24(基于CentOS或者Redhat5.4操作系统)
- usb3.0的driver porting——基于linux kernel3.18的usb gadget udc driver & net3380 driver porting
- linux下的软连接和硬连接
- android安装Linux,玩转Android
- CentOS 6 NFS的安装配置
- Linux死锁分析
- Linux 服务器--Iptables 端口转发
- Linux查看CPU个数
- 如何得到linux的pagesize