Linux信号处理

Linux信号处理函数详解 一下内容引述《Linux/Unix系统编程详解》 设计信号处理函数 信号处理函数设计得越简单越好,这样降低引发竞争条件的风险。 两种常见设计 信号处理函数设置全局性标志变量并退出,主程序对此标记进行周期性检查,一旦置位随机采取相应动作; 信号处理器函数执行某种类型的清理动作,接着终止进程或者使用非本地跳转将栈解开并将控制返回到主程序中的预定位置; 可重入函数与异步信号安全函数 可重入函数 首先区分单线程程序和多线程程序。典型的UNIX程序都具有一条执行线程,贯穿程序始终,CPU围绕单条执行逻辑来处理指令 阅读详情

由于在下能力相当有限,有不当之处,还望大家批评指正^_^


一、 信号概念


  • 信号(signal)是软中断。
  • 信号提供了一种处理异步事件的方式。
  • 当各种各样的事件发生时,程序相应的会收到各种各样的信号。
  • 对于大部分信号,程序可以自行决定如何处理他们。

程序在什么情况下会收到信号,下面是一些例子
执行某条指令,产生了异常
   (例如, 访存指令访问无效内存时收到SIGSEGV信号,执行非法指令收到SIGILL信号)
执行某些不合适的操作
  (例如,写破列的管道收到SIGPIPE信号,后台程序向控制台打印信息收到SIGTTOU信号)
发生了一些与当前程序有关的事情
  (例如,子进程退出后父进程收到SIGCHLD信号,定时器时间到了收到SIGALRM信号)
程序之间相互发送信号
  (例如, 程序之间通过信号进行协作)

通过man 7 signal命令可以查看Linux下的信号说明。
下面列出了此命令输出的一些信号,包括信号的编号,默认处理方式。
注意,同一信号,在不同CPU架构下的编号可能不一样。例如,像SIGUSR1, SIGCONT等。






二、 信号处理

对于一个信号如何处理,程序有如下3种选择
  • 忽略 
  • 捕获并处理 
  • 让系统按默认方式处理
注意:   SIGKILL与SIGSTOP信号,即无法被忽略,也无法被捕获。

Linux信号处理,有两种机制, 一种是传统的,一种是现代的。

总得来说,传统的信号处理机制有多种缺陷,因此还是不用为好。
另外,关于程序处理信号的具体方法,本文就不介绍了。《UNIX环境高级编程》对这些知识说得已经非常好了。

本文着重讲讲信号处理机制中的某些特殊之处。


三、 多线程程序中的信号处理

程序中对于某个信号如何处理的设置,对所有线程都是相同的。
换句话说,对任一信号设置的处理方式,以及相应的信号处理函数,对于所有线程都是共享的。
每个经程,通过pthread_sigmask设置自己要阻塞的信号。
问题是,这样的话,信号来了,具体由哪个线程谁处理呢???
这要分几种情况来讨论:

1. 外界向本进程发送的信号(通过sys_kill系统调用)
答案是,如果没有特殊情况,都是主线程处理。如果主线程不能处理,则选出一个线程来处理。
具体如何实现的,下面贴出内核中的相关代码

	/*
	 * Now find a thread we can wake up to take the signal off the queue.
	 *
	 * If the main thread wants the signal, it gets first crack.
	 * Probably the least surprising to the average bear.
	 */
	if (wants_signal(sig, p))
		t = p;
	else if (!group || thread_group_empty(p))
		/*
		 * There is just one thread and it does not need to be woken.
		 * It will dequeue unblocked signals before it runs again.
		 */
		return;
	else {
		/*
		 * Otherwise try to find a suitable thread.
		 */
		t = signal->curr_target;
		while (!wants_signal(sig, t)) {
			t = next_thread(t);
			if (t == signal->curr_target)
				/*
				 * No thread needs to be woken.
				 * Any eligible threads will see
				 * the signal in the queue soon.
				 */
				return;
		}
		signal->curr_target = t;
	}




2. 直接向某线程发送的信号(通过sys_tkill系统调用)
答案是,只会由此线程自己处理。

3.  线程执行相关指令产生的信号
某线程执行指令,导致产生了SIGSEGV或SIGILL,只会由产生此信号的线程自己处理。


最后,如何让线程专心做事,不被进程收到的信号打断呢。
同时,信号又能够得到妥善的处理。一种解决方法是:所有线程均阻塞所有process-directed信号,由一个线程轮询接收处理这些信号。



四、内核中的相关实现(引用内核版本2.6.32)
1. 内核何时处理信号
任务进入内核态后,在即将返回用户态之前,内核检查当前任务是否有信号需要处理。有的话,就处理信号。
任务一般会因为中断、系统调用、指令异常这几个原因,进入内核态。但不管是哪一种,在返回用户态之前,内核都会做信号方面的检查与处理。这个流程是一样的。
以i386为例,其代码在如下文件中。
arch\x86\kernel\entry_32.S


2. 信号处理代码简析

a). 信号处理总入口
static void do_signal(struct pt_regs *regs)
他由do_notify_resume调用


b). get_signal_to_deliver中处理被忽略的信号,以及按默认方式处理的信号


c). handle_signal中处理用户设定了要捕获处理的信号

3. 内核如何重启被信号打断的系统调用 


以ioctl为例。在x86_64下,其系统调用号为16。
见arch\x86\include\asm\unistd_64.h


ioctl的C库函数汇编代码如下:
000000000040af30 <__ioctl>:
40af30: b8 10 00 00 00      mov    $0x10,%eax
40af35: 0f 05               syscall 
40af37: 48 3d 01 f0 ff ff   cmp    $0xfffffffffffff001,%rax
40af3d: 0f 83 ad 23 00 00   jae    40d2f0 <__syscall_error>
40af43: c3                  retq   
40af44: 90                  nop    
40af45: 90                  nop 




handle_signal中的代码片断如下:
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
regs->ax = -EINTR;
break;
}
/* fallthrough */
case -ERESTARTNOINTR:
regs->ax = regs->orig_ax;
regs->ip -= 2;  //等于回到__ioctl中调用syscall之前的地方了
break;


4. 用户态信号处理函数的执行
当线程要从内核态回到用户态时,如果有信号要处理,那么就不是回到用户态原先因为进内核而被中断的地方执行了。而是回到用户设置的信号处理函数的地址处开始执行,就好像线程当初进入内核前正要执行信号处理函数一样。
以x86_32,传统信号处理方式为例。
代码在ia32_setup_frame中
内核将用户态程序现场修改为,回到用户态正好要执行的下一条指令,就是用户态信号处理函数的第一条指令。这样,回到用户态,就从用户态信号处理函数第一条指令开始执行了。

5. 用户态信号处理函数的返回
以x86_32,传统信号处理方式为例。
内核在ia32_setup_frame中为返回做好了准备

用户态信号处理函数的栈帧中,返回地址被内核赋了相应的值。即用户态信号处理函数在返回时,会返回到内核事先安排好的地方继续执行。其实就是调用__NR_ia32_sigreturn,对应sys_sigreturn。
sys_sigreturn中就作了现场环境的恢复。
主要是restore_sigcontext这个函数。
他从栈里面取出现场环境数据,进行恢复。
这些栈里面的数据,则是前面在ia32_setup_frame 处理中,通过调用函数ia32_setup_sigcontext进行保存的。

linux信号处理函数的可重入性 在信号处理函数中,尽量使用可重入的函数接口(即操作的数据都是在堆栈上,不涉及全局变量),否则会引起数据的崩溃。一个简单的演示程序可以说明这点。 #include #include int a=0; void  handleSig5(int num, siginfo_t * info, void * no_used) { a = 5; printf("before 阅读详情

相关推荐

linux0.11信号处理

linux中的信号处理函数提供了对程序异步处理的功能,比如键盘按下ctrl+c键,该操作将产生一个SIGINT信号,并被发送到当前前台的进程中。内核采用一个无符号长整形变量中(32bit)的每一个比特位来表示不同的信号,因此最多可以定义32种信号。对于一个进程来说,当收到一个信号时,有3种不同的处理方式: 1. 忽略该信号。其中SIGKILL和SIGSTOP不能忽略。 2. 捕获该信号。调用s

FK的专栏 1367

Linux操作系统学习(信号处理)

学习笔记

hxMGE的博客 893

Linux系统编程(信号处理机制)

本篇文章我们来讲解信号的处理机制,信号处理在Linux操作系统中必不可少,这一点值得大家注意,信号又会与中断,异常一起讨论,那么下面我们就来看看到底什么是信号吧。本篇文章就讲解到这里,大家看完后可以好好实验一下。

m0_49476241的博客 1413

linux 信号处理

1 linux中的信号Linux中的信号是用来通知进程发生了异步事件。在原理上,一个进程收到一个信号与一个处理器收到一个中断请可以看成一致的。信号是linux进程间通信机制中的唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也无法提前感知信号什么时候到达由谁发送。当然内核也会因为内部事件给进程发送信号。信号机制除了基本通知功能外,还可以传递附加信息。常用的信号发送函数有raise kill等 常用的信号注册函数有signal、sigaction等。2 源码分析2.1 信号发送此处拿

zhuguanghong的博客 854

AI 代码生成工具的质量评估体系

基础需求层包括响应速度(Response Time)和界面友好性(UI Friendliness),期望需求层涵盖智能提示(Smart Suggestions)和个性化配置(Personalization),兴奋需求层则涉及多模态交互(Multimodal Interaction)和代码进化(Code Evolution)。在金融领域,代码审计合规性(Compliance Audit)权重应提升至40%,而在Web开发中,API兼容性(API Compatibility)的权重需达到35%。

2503_92418637的博客 3375

断点回归(regression discontinuity design)学习笔记

本篇博文主要是对断点回归的一些学习和总结~ 学习材料如下: 1 断点回归设计RDD分类与操作案例 2 RDD断点回归, Stata程序百科全书式的宝典 3 断点回归设计的前沿研究现状, RDD 4 让“跳跃”更有意义:断点回归设计(RDD) 5 Stata: 断点回归 (RDD) 教程 6 怎么用通俗的语言解释断点回归?它与DID的区别是什么 7 Watering Down Environmental Regulation in China,Guojun He, Shaoda Wang, Bing Zhan

Claire_chen_jia的博客 9万+

LINUX 信号处理_linux 信号处理流程

1、字段sa_handler是一个函数指针,用于指向原型为void handler(int)的信号处理函数地址,sighandler_t是信号捕捉函数,由signal函数注册,注册以后,在整个进程运行过程中均有效,并且。4、字段sa_mask是一个包含信号集合的结构体,该结构体内的信号表示在进行信号处理时,将要。2、如果信号处理函数正在处理信号, 并且还没有处理完毕时,又发生了一个同类型的信号,这时。1、注册一个信号处理函数,并且处理完毕一个信号之后,是否需要重新注册,才能够捕捉下一个。

2401_86402545的博客 1505

深入解析Cuk、Zeta和Sepic拓扑:非隔离型开关电源的设计奥秘

本文深入解析了Cuk、Zeta和Sepic三种非隔离型开关电源拓扑的设计奥秘。它们均能实现升降压转换,但特性各异:Cuk拓扑输出反向电压,输入输出纹波极低;Sepic拓扑输出同极性电压,应用广泛;Zeta拓扑输出纹波小,适合精密供电。文章详细对比了其电路结构、工作原理、核心公式及选型指南,帮助工程师根据输入电压范围、输出极性及纹波要求,灵活选择最合适的拓扑方案。

weixin_28308325的博客 479

【Linux信号处理】

1、忽略2、终止进程3、终止进程并产生core文件(记录内存映像)4、停止5、继续6、捕获并处理 (在信号发生前,先向内核注册一个函数,当信号来临时系统会自动执行该函数)

electronic_J的博客 1426

跨平台商品模型大解析:亚马逊 vs 阿里 vs 拼多多

本文深入探讨了亚马逊、阿里巴巴和拼多多三大电商平台的商品模型设计,分析了它们在变体关系、商品抽象层级和SKU定义等方面的异同。亚马逊模型以物流和变体为中心,强调全球仓配体系下的标准化管理;阿里模型采用多视角的弹性结构,适用于多类目、多品牌、多卖家环境;拼多多模型则结合平台标准化与商家个性化,适合短期促销和快速上新场景。文章还提供了实践建议,帮助自研电商平台或商品中台的开发者选择合适的商品结构,并强调了商品模型在电商系统中的核心作用。通过对比分析,本文旨在为读者提供商品建模的启发和参考。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 13万+

【图像去噪】论文复现:CLIP用于图像去噪提升泛化性!CLIPDenoising的Pytorch源码复现,跑通CLIPDenoising全流程,图文结合,网络结构梳理和拆解,对应源码注释!

论文题目:Transfer CLIP for Generalizable Image Denoising —— 用于可泛化图像去噪的转移CLIP。【图像去噪】论文精读:Transfer CLIP for Generalizable Image Denoising(CLIPDenoising)CLIPDenoising理论部分详解见上面对应的论文精读,本文以源码为主,理论部分只是粗略回顾。启发:多看其他领域的文章,分析是否能应用在去噪领域,这是产生idea的要素之一;

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 1414

sigv linux 信号,LINUX 信号处理

转自:http://zhangcy.anytome.com/20060321121911820418131452020050715/35.xml一 入门信号是有雷同的或不同的历程向一个历程递交的事件。信号等闲用来向一个历程通知失常事件。术语:发生(generate):当导致信号发生的事件揭示时,例如硬件失常,就发生一个针对某个历程的信号递交(deliver): 当历程对发给它的信号历程处理时,称为...

weixin_36360543的博客 186

【Unity URP渲染管线下Shader的自定义物体半透明和投影半透明效果_半透明案例分享】

Unity Shader Graph URP渲染管线下的自定义半透明效果_半透明案例分享

暴走约伯的博客 3295

linux信号处理函数

linux中信号的处理一般分为四步 1、信号集的安装和登记 2、信号集操作 3、信号的发送 4、信号的接收  下面分阶段详细说明 1、信号集的安装和登记 使用sigaction函数对信号进行安装和登记 ngx_init_signals(ngx_log_t *log) {     ngx_signal_t      *sig;     struct sigaction

BOKE 907

损失函数大汇总(三十八)(AUCPR Loss附公式推导与代码)

本文系统介绍了AUCPR Loss的原理与应用。针对不平衡分类任务中AUC指标不够敏感的问题,提出通过优化PR曲线面积(AUCPR)来提升模型性能。文章详细推导了AUCPR的可微近似实现:首先用sigmoid函数软化阈值判断,构造可微的TP/FP/FN计数;然后基于软Precision和Recall计算近似PR曲线面积;最后通过数值积分得到可优化的损失函数。特别讨论了温度参数τ对训练稳定性的影响,并比较了AUCPR与AUC、AP等指标的异同。该方法适用于医学筛查、欺诈检测等极端不平衡场景,能更准确反映模型对

悦学共鸣,温柔以待,汇聚光芒,共同成长 441

【OCPP】ocpp1.6协议3.3章节:功能配置文件及接口

Smart Charging Profile中定义了4个接口请求,即GetCompositeSchedule、ClearChargingProfile、SetChargingProfile和ClearCache等。Smart Charging: 包含智能充电相关的功能,如计划充电,报告充电计划,并改变充电速度。Core: 包含电动汽车充电相关的基础功能,如启动和停止充电,更改充电配置,报告充电状态等。Reservation: 包含预约服务相关的功能,如创建,取消和更改预约。

qq_53871375的博客 2171

Linux信号处理详细介绍

建立在早期的信号处理机制(1-31)的信号是不可靠信号,意味着它不支持排队,可能会丢失,如果同一个信号连续产生多次,进程可能只相应一次,但是多个不同的信号,会按照时间顺序从后往前相应。2、当信号处理完后可能会返回产生信号的代码继续运行,如果我们捕获并处理段错误、算术异常等信号可能会产生死循环,正确的处理段错误、算数异常信号应该是备份数据并直接结束程序。当信号产生时,内核会在其维护的信号表中为对应的进程设置与该信号对应的标记,这个过程叫做递送。功能:设置要屏蔽的信号、这些信号是存储在信号集里面。......

sorryking_的博客 662

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Linux 信号处理函数

#include <stdio.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <ostream> #include <cerrno> static int s_handle_count = 0; static std::str...

忧桑的小兔子 2649

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

linux信号处理机制的原理

linux信号处理机制的原理   信号处理机制的原理:     内核给一个进程发送软中断信号的方法,是在进程所在的进程表项的信号域设置对应于该信号的位。这里要补充的是,如果信号发送给一个正在睡眠的进程,那么要 看该进程进入睡眠的优先级,如果进程睡眠在可被中断的优先级上,则唤醒进程;否则仅设置进程表中信号域相应的位,而不唤醒进程。这一点比较重要,因为进程 检查是否收到信号的时机是:

liuchenhaha的专栏 423

假人有限元模型

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

Linux信号处理机制

戳蓝字「TopCoder」关注我们哦!信号是一种异步处理的软中断,内核会发送给进程某些异步事件,这些异步事件可能来自硬件,比如除0或者访问了非法地址;也可能来自其他进程或用户输入,比如...

luoxn28的专栏 319
上一篇: pci设备学习笔记
下一篇: 小兵以太网测试仪Linux版(Linux发包工具)使用说明
无忧老猪
博客等级 码龄18年 200粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值