Linux多线程编程和信号易疏忽的一个例子
来源:互联网 发布:淘宝卖家如何消除差评 编辑:程序博客网 时间:2024/06/05 11:43
转自:http://blog.csdn.net/anxuegang/article/details/6636410
这几天把一个网络流量采集器程序基本改好了,原来在main函数中把几个子线程启动后就睡10分钟后开始清理子线程后退出。现在想改成子线程启动后主线程进入无限睡眠,直到收到SIGTERM或SIGINT。主程序如下:
其他头文件
#include <signal.h> //信号处理所需要的头文件
int main(int argc, char * argv[]){
//其他所需要的变量声明
sigset_t sig_set,sig_pending;
// 设置信号阻塞
sigemptyset(&sig_set);
sigaddset(&sig_set,SIGTERM);
sigaddset(&sig_set,SIGINT);
sigprocmask(SIG_BLOCK,&sig_set,NULL);
启动几个子线程
...........
// 设置信号阻塞
sigemptyset(&sig_set);
sigaddset(&sig_set,SIGTERM);
sigaddset(&sig_set,SIGINT);
sigprocmask(SIG_BLOCK,&sig_set,NULL);
//主线程进入睡眠,等待信号到达后跳出睡眠
while(1){
sigpending(&sig_pending);
if(sigismember(&sig_pending, SIGTERM)||
sigismember(&sig_pending,SIGINT)){
break;
}
sleep(2);
}
//子线程退出情理
................
return 0;
}
程序运行后发现 当按下Ctrl+C后程序没有出现子线程退出时的信息而是立刻退出,非常奇怪。
仔细分析了一下,发现问题在于忽略了Linux下的多线程模型的特点。
Linux下的线程实质上是轻量级进程(light weighted process),线程生成时会生成对应的进程控制结构,只是该结构与父线程的进程控制结构共享了同一个进程内存空间。 同时新线程的进程控制结构将从父线程(进程)处复制得到同样的进程信息,如打开文件列表和信号阻塞掩码等。由于我们是在子线程生成之后修改了信号阻塞掩码,此刻子线程使用的是主线程原有的进程信息,因此子线程仍然会对SIGINT和SIGTERM信号进行反应,因此当我们用Ctrl+C发出了SIGINT信号的时候,主进程不处理该信号,而子进程(线程)会进行默认处理,即退出。子进程退出的同时会向父进程(线程)发送SIGCHLD信号,表示子进程退出,由于该信号没有被阻塞,因此会导致主进程(线程)也立刻退出,出现了前述的运行情况。因而该问题的一个解决方法是在子线程生成前进行信号设置, 或在子线程内部进行信号设置。 由于子线程是往往是一个事务处理函数,因此我建议在简单的情况下采用前者,如果需要处理的信号比较复杂,那就必须使用后一种方法来处理。这样,以上的程序逻辑改为如下就可以了:
#include <signal.h> //信号处理所需要的头文件
int main(int argc, char * argv[]){
//其他所需要的变量声明
sigset_t sig_set,sig_pending;
启动几个子线程
...........
//主线程进入睡眠,等待信号到达后跳出睡眠
while(1){
sigpending(&sig_pending);
if(sigismember(&sig_pending, SIGTERM)||
sigismember(&sig_pending,SIGINT)){
break;
}
sleep(2);
}
//子线程退出情理
................
return 0;
}
- Linux多线程编程和信号易疏忽的一个例子
- Linux多线程编程和信号易疏忽的一个例子
- Linux下多线程编程与信号处理易疏忽的一个例子
- Linux下多线程编程与信号处理易疏忽的一个例子
- Linux下多线程编程与信号处理易疏忽的一个例子
- Linux下多线程编程与信号处理易疏忽的一个例子
- Linux下多线程编程与信号处理易疏忽的一个例子[转]
- linux 多线程编程的信号问题
- Linux多线程编程(不限Linux)——本文一个例子展开,介绍Linux下面线程的操作、多线程的同步和互斥。
- 基本多线程编程的一个例子
- linux 多线程编程例子
- Linux多线程编程例子
- Port-forwarding 和 HttpServletRequest 和一个疏忽引发的bug
- Linux多线程的一个小例子
- linux内核中的信号机制--一个简单的例子
- Linux多线程编程(三)互斥锁和信号量编程例子
- 一个疏忽导致的问题
- LINUX下多线程和信号
- MongoDB自学笔记1----1.1NoSQL是什么?
- Linux Pthread_kill
- Creative Commons
- 现在共有13个球,这批球重有一个球的质量和其它球的质量不同(轻重未知)。给你一个天平,至多只有三次的称量机会,怎样将那个质量不一样的球找出来?
- 十进制转换为任意进制(栈 c++版)
- Linux多线程编程和信号易疏忽的一个例子
- Unity3D中物体查找和关联方法
- Ubuntu下切换登录管理器
- 关于场景中的物件和鼠标事件的触发
- 电源防接反
- Unity3D中的预制件(Prefab)的创建和使用说明!!!
- Android开发之Ubuntu上Eclipse不显示手机设备
- BT17无线网一键破解,一键式破解WPA,WPA2,AES不再是梦想
- 注重实效的程序员(The Pragmatic Programmer)