Linux下多线程编程与信号处理易疏忽的一个例子(转)

Linux下多线程编程与信号处理易疏忽的一个例子[@more@]

这几天把一个网络流量采集器程序基本改好了,原来在main函数中把几个子线程启动后就睡10分钟后开始清理子线程后退出。现在想改成子线程启动后主线程进入无限睡眠,直到收到SIGTERM或SIGINT。主程序如下:
其他头文件
#include //信号处理所需要的头文件
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 //信号处理所需要的头文件
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;

}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9417382/viewspace-953383/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9417382/viewspace-953383/

深入解析MOS管电容特性:从基础理论到高频应用 本文深入解析了MOS管的电容特性,从基础物理结构出发,详细拆解了栅氧电容、重叠电容和结电容的成因与影响。文章重点探讨了电容值随工作状态变化的非线性特性,并分析了其在CMOS高频开关电源、射频电路等应用中的关键作用,包括开关损耗、米勒效应、信号完整性挑战以及如何将电容特性转化为可控元件(如MOS变容管)的机遇。最后提供了从选型、仿真到PCB布局的实战设计指南。 阅读详情

相关推荐

从透射谱到能量分布:用Rsoft破解光纤光栅耦合模式的3个关键技巧

本文面向光通信工程师与研究者,分享了利用Rsoft软件深入分析光纤光栅耦合模式的三个关键技巧。通过配置场监视器观察XY截面能量分布、利用传播动画追踪动态过程,并结合模式求解器精准判定相位匹配,帮助用户超越透射谱分析,直观可视化能量从纤芯到包层的耦合与流动,从而优化器件设计。

weixin_29290963的博客 420

Linux下多线程编程与信号处理易疏忽的一个例子

这几天把一个网络流量采集器程序基本改好了,原来在main函数中把几个子线程启动后就睡10分钟后开始清理子线程后退出。现在想改成子线程启动后主线程进入无限睡眠,直到收到SIGTERM或SIGINT。主程序如下:其他头文件#include <signal.h> //信号处理所需要的头文件int main(int argc, char * argv[]){ //其他所...

weixin_34319111的博客 142

深入解析Lora SX1268:从基础配置到高级应用

本文深入解析了LoRa SX1268芯片从基础配置到高级应用的全过程。详细介绍了LoRa与FSK模式选择、核心参数(BW、SF、CR、LDRO)的配置策略、数据帧结构、缓冲区管理以及CAD模式等关键概念,旨在帮助开发者充分发挥SX1268在远距离、低功耗物联网通信中的潜力,并提供实用的调试技巧。

weixin_29168393的博客 117

多线程与信号

多线程环境的信号递送 在一个单进程中,信号会打断进程的执行,并且递送到进程中处理,而对于多线程环境,信号会递送给其中的一个线程,这个被递送的线程是不确定的。每个线程存在自己的信号屏蔽字,可以通过如下函数设置: int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset); 该函数设置线程对应的信号屏蔽字,被屏蔽的信号会被挂...

程序猿Ricky的日常干货 5054

从零构建企业级多智能体系统:LangGraph 全流程实战 + 部署指南(含代码与架构图)

> 在大模型应用爆发的今天,如何构建一个可协作、可调试、可部署的多智能体系统?LangGraph 正在成为工程师的新宠。本文从原理剖析、流程建模、代码实战到前后端部署,手把手带你用 LangGraph 构建一个企业级 AI 助理系统,整合财务分析、法务审阅、报告生成与图表可视化等 Agent 模块,全面打通从用户输入到报告输出的全链路闭环。适合有工程思维的 AI 架构师、Agent 研发人员、以及大模型项目实践者。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 3449

【雷达仿真 | FMCW TDMA-MIMO毫米波雷达信号处理仿真(可修改为DDMA-MIMO)】

1、FMCW叫做调频连续波,调频连续波有步进调频连续波(SFMCW)、线性调频连续波(LFMCW),以及其他非线性调频连续波。LFMCW有锯齿波和三角波等等;锯齿波有恒定调制周期的锯齿波和非恒定周期的锯齿波。Introduction to mmwave sensing:FMCW radars.pdf和The fundamentals of millimeter wave sensors。2、MIMO是多输入多输出(Multiple input Multiple output),也就是多发多收。

【调皮连续波】雷达技术领域知识博主 1万+

关于SIGCHLD的不排队,丢弃的问题

signal(SIGCHLD, SIG_IGR); //忽略SIGCHLD信号,这常用于并发服务器的性能的一个技巧                          //因为并发服务器常常fork很多子进程,子进程终结之后需要                          //服务器进程去wait清理资源。如果将此信号的处理方式设为                          //忽略,

ang639 1106

docker安装fastdfs+nginx配置

docker安装fastdfs+nginx,实现图片或文件的上传与下载

weixin_47325126的博客 2192

除非必要,不要使用Linux信号

Linux 信号处理注意事项不要使用linux的信号不要处理SIGSEGV不要处理SIGCHLD不要处理SIGCONT信号处理函数中不应该有复杂的业务逻辑为什么你不应该使用信号? 不要使用linux的信号 除非必要,不要使用linux的信号做任何事情。因为这套工具的使用非常容易出错,对开发人员的基础知识和经验要求较高。 不要处理SIGSEGV 除非必要,不要处理SIGSEGV。处理错误会导致进程段错误后进入处理段错误的死循环。 不要处理SIGCHLD 除非必要,不要处理SIGCHLD。处理错误会产生僵尸进程

madbunny的专栏 383

【零基础入门unity游戏开发——unity通用篇14】unity特性相关的知识(基于unity6开发介绍)

unity特性相关的知识(基于unity6开发介绍)

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1204

电磁兼容(EMC):一文读懂过电应力(EOS)

过电应力(EOS)是指元器件承受的电流或电压应力超过其允许的最大范围。产品的电磁兼容(EMC)失效的一种常见模型为过电应力(EOS),也是电子产品失效的最常见的情况之一。过电应力基本与半导体器件相关,EOS事件包括有:静电放电(ESD)、雷击、系统瞬态、电磁脉冲、充电等。本文将详细讨论一下产品设计中如何关注EOS设计。

linkking27的博客 6485

关于SIGCHLD信号的处理

进程一章讲过用wait和waitpid函数清理僵尸进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。采用第一种方式,父进程阻塞了就不能处理自己的工作了;采用第二种方式,父进程在处理自己的工作的同时还要记得时不时地轮询一下,程序实现复杂。 其实,子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD

继续微笑lsj 1494

软件产品国际化:前后端及App多语言版本解决方案(超详细实现过程)

多语言版本解决方案是应对全球化趋势的关键策略,它通过构建灵活且可扩展的架构,支持软件产品在不同语言和文化环境下的顺畅运行与展示。此方案涵盖了前端多语言界面实现、后端多语言数据处理及大数据环境下的多语言支持等多个层面,确保公司能够高效地推出适应全球用户多样化需求的软件产品。在前端多语言界面实现方面,解决方案采用了国际化与本地化的结合方法。国际化过程确保软件的功能和代码设计能够处理多种语言和文化习惯,而本地化则针对特定地区进行界面和内容的调整。

大模型大数据攻城狮的专栏 2753

Linux下多线程编程与信号处理易疏忽的一个例子[转]

原文地址:http://www.cnblogs.com/shipfi/archive/2008/02/20/1075611.html这几天把一个网络流量采集器程序基本改好了,原来在main函数中把几个子线程启动后就睡10分钟后开始清理子线程后退出。现在想改成子线程启动后主线程进入无限睡眠,直到收到SIGTERM或SIGINT。主程序如下:其他头文件#include //信号处理所需要的头文件in

寥若晨星 673

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Linux多线程编程和信号易疏忽的一个例子

转自:http://blog.youkuaiyun.com/anxuegang/article/details/6636410 这几天把一个网络流量采集器程序基本改好了,原来在main函数中把几个子线程启动后就睡10分钟后开始清理子线程后退出。现在想改成子线程启动后主线程进入无限睡眠,直到收到SIGTERM或SIGINT。主程序如下: 其他头文件 #include //信号处理所需要的头文件

599

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

多线程开发

 引语随着计算机中央处理器主频的不断上升,能耗问题也成为当今一大主要问题,因为这个问题的出现,随即出现了双核处理器以及多核处理器,大大降低了计算机的能耗。但随之而来的问题是,如何充分发挥多核平台的处理性能,对于当今的开发人员来说是一个机遇和挑战,这就是为什么我们要强调多线程开发的原因。下面将以一些理论和实例讲解如何进行多线程编程。多线程编程入门 多线程编程——基础

complier2的专栏 1357

线程池 c linux 编程,关于c++:linux-c编程之高效线程池如何实现无琐化

大多数线程池实现都离不开锁的应用,如互斥量pthread_mutex*联合条件变量pthread_cond*。家喻户晓,锁的应用对于程序性能影响较大,尽管现有的pthread_mutex*在锁的申请与开释方面做了较大的优化,然而,线程池的实现是能够做到无锁化的。1.常见线程池实现原理如上图所示,工作队列由主线程和工作者线程共享,主线程将工作放进工作队列,工作者线程从工作队列中取出工作执行。共享工作...

weixin_33502772的博客 229

别再让指针乱跑了!Linux C/C++ 段错误(Segmentation Fault)的5个常见坑与排查实战

本文深入探讨Linux C/C++开发中常见的段错误(Segmentation Fault)问题,详细分析空指针解引用、野指针、数组越界等5大常见陷阱,并提供dmesg、GDB、Valgrind等专业工具的实战排查方法,帮助开发者有效解决内存访问错误。

weixin_30329623的博客 382

线程安全 可重入函数

一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误。 《多线程编程指南》中定义,可以被信号控制器安全调用的函数被称为"异步信号安全"函数。 因此,我认为可重入与异步信号安全是一个概念。 有人将可重入函数与线程安全函数混为一谈,我认为是不正确的。 这里引用CSAPP中的描述来说明一

crazy_programmer_p的专栏 821
上一篇: 简述 Linux 文件系统的目录结构(转)
下一篇: 红帽Linux平台:虚拟化技术发展详解(2)(转)
congwan5321
博客等级 码龄11年 1粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值