li
  当前位置:主页 > 操作系统Redhat Linux > 文章内容
li
Linux下多线程编程与信号处理易疏忽的一个例子
来源: www.ixdba.net  作者: IXDBA.NET技术社区    时间:2008-02-23   阅读:3  
这几天把一个网络流量采集器程序基本改好了,原来在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 手动下载和安装 Java R...   下一篇: Linux上glibc的man手册关于timev...
li
 §相关评论  
 热点文章

·使用pam_abl防止SSH遭暴力破解
·redhat linux 5上telnet的开启
·linux命令行下如何更换使用的s
·xhost unable to open display
·文件系统出现不一直的原因和基
·linux系统下磁带机的简单操作命
·tar与磁带机操作命令
·linux系统建立终端和登录系统
·如何配置/etc/fstab或autofs让
·如何安装和升级一个RPM软件包?
·如何在新添加的磁盘上创建EXT3
li
 编辑推荐
·使用pam_abl防止SSH遭暴力破解
·redhat linux 5上telnet的开启
·linux命令行下如何更换使用的s
·xhost unable to open display
·文件系统出现不一直的原因和基
·linux系统下磁带机的简单操作命
·tar与磁带机操作命令
·linux系统建立终端和登录系统
·如何配置/etc/fstab或autofs让
·如何安装和升级一个RPM软件包?
·如何在新添加的磁盘上创建EXT3
li
 相关篇章
·为 Linux 手动下载和安装 Java R...
·Linux多线程编程和Linux 2.6下的...
·红帽Linux平台:虚拟化技术发展详...
·红帽Linux平台:虚拟化技术发展详...
·Linux2.6内核驱动移植
·linux系统优化:系统状态查看工具...
·鸟哥:DNS 服务器配置全攻略
·linux学习方法论-为您学习linux...
·Ssh,scp自动登陆方法
·Linux操作系统的内存管理特性
·Linux上glibc的man手册关于timev...
·简述 Linux 文件系统的目录结构
·Linux集群的安装与并行计算
·加固Linux服务器
·Linux 文件访问原语
·Linux下XFConfig的有效使用
·使用Linux的8个经典技巧
·Linux核心数据结构
·RedHat Linux下防火墙配置入门必...
·Solaris到Linux应用的移植
 
li
设为首页 | 关于我们 | 技术服务 | 收藏本站 | 网站地图 | 联系方式 | 本站友情连接