进程信号简述

article/2025/7/23 9:09:40

01. 信号产生

生活中的信号类比(交通信号灯、警报),当产生这些信号时,我们会立马想到对应的动作。在Linux中,信号是事件发生对进程的通知机制亦称软件中断,由操作系统内核、进程本身或者其他进程向目标进程异步事件发送机制(即收到某种信号,并不会立马去执行)。通知进程发生某种预定义的时间,要求进程作出相应响应。信号与硬件中断相似之处在于会打断程序执行流程。

1.1 认识常见信号

45% 20% 15% 20% 常见信号类型占比 终止进程 暂停进程 核心转储 其他功能
  • 硬件异常
    • 如内存越界(SIGSEGV
    • 除零错误(SIGFPE
    • 由内核自动生成
  • 系统调用:
    • kill():向指定进程发送信号
    • raise():进程向自身发送信号
    • alarm():设置定时器,超时后发送 SIGALRM
  • 终端输入:
    • Ctrl+C:SIGINT(终止进程)
    • Ctrl+Z:SIGTSTP(暂停进程)
    • Ctrl+\:
  • 软件条件:
    • 子进程退出时,父进程收到 SIGCHLD
    • 定时器到期(如 alarm())触发信号
  • 核心转储 :

1.2 信号的分类

信号分为两大类。(编号1-31)为传统信号信号,内核向进程通知且递送一次,(编号34-64)为实时信号使信号按序递送。


1.3 信号处理方式

  • 默认动作: 部分是终止自己,暂停等
  • 忽略动作: 是一种信号处理的方式,只不过动作就是什么都不干
  • 自定义动作: 使用signal方法修改信号的处理动作。(即用户程序员编写的函数:将默认动作转化为自定义动作)

1.4 改变信号处理方式

在这里插入图片描述


02. 信号阻塞

2.1 概念悉知

  • 实际执行信号的处理动作称为信号递达(Delivery)
  • 信号从产生到递达之间的状态,称为信号未决(Pending)。
  • 进程可以选择阻塞 (Block )某个信号。
  • 被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.
  • 阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。
信号被阻塞
信号未阻塞
解除阻塞后
信号产生
未决集
递达

信号产生后会稍后递达给某进程,信号在产生和到达期间会一直处于pending等待状态。


2.2 信号在内核中的表示

每个进程都有一个信号屏蔽字亦称阻塞信号集,一个 sigset_t 类型的位图,每一位对应一个信号(如 SIGINTSIGQUIT 等)。用来标记哪些信号当前被阻塞。被阻塞的信号若已产生,会进入未决状态,直到阻塞被解除才会触发处理。位为1生效,0不生效。


2.2.1 block与pending之间联系

pending集是信号产生后的暂存区,block是控制信号是否能从pending暂存区递交给进程的开关

  • block:决定哪些信号会被阻塞,近而将其放入未决信号集
  • pending:记录已产生但未被处理的信号(因被阻塞或正在处理其他信号),本质是这个信号被暂存task_struct信号为途中?

其中block位图用于表示进程是否阻塞。pending位图用于是否有信号写入(信号是否产生,信号产生时,内核在进程控制块中设置该信号的pending位图,直到信号抵达才消失)。handler函数指针数组用于进程执行何种动作(其中存放的是动作函数指针,每个信号的编号就是其数组下标)。

在这里插入图片描述


位=1
位=0
解除阻塞
执行期间
信号产生
blocked位图
pending位图
handler函数
临时sa_mask

2.3 关键系统调用

2.3.1 信号集操作函数

sigset_t 本质上是一个位图,每一位代表一个信号。当某一位被设置为 1 时,表示对应的信号被包含在信号集中;为 0 则表示不包含。使用者只能调用以下函数来操作sigset_t变量,不用关注内部数据。

在使用sigset_t类型的变量之前,一定要调用sigemptyset()函数初始化一个未包含任何成员的信号集或者sigfillset()函数则初始化一个信号集,使其包含所有信号(包括所有实时信号)。

#include <signal.h>
int sigemptyset(sigset_t *set);    // 清空信号集,置0
int sigfillset(sigset_t *set);     // 填充所有信号, 置有效状态1?

信号集初始化后,可以分别使用 sigaddset()sigdelset()函数向一个集合中添加或者移除单个信号。使用sigismember()测试信号是否是信号集set的成员。

#include <signal.h>
int sigaddset(sigset_t *set, int signo); // 添加单个信号
int sigdelset(sigset_t *set, int signo); // 删除单个信号
int sigismember(const sigset_t *set, int signo); // 判断信号是否存在

2.3.2 信号掩码(阻塞信号传递)

内核会为每个进程维护一个信号掩码,即一组信号,并将阻塞其针对该进程的传递。如果将遭阻塞的信号发送给某进程,那么对该信号的传递将延后,直至从进程信号掩码中移除该信号,从而解除阻塞为止。

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数 :

  • how:指定了sigprocmask()函数想给信号掩码带来的变化。
    • SIG_BLOCK:set包含了我们希望添加到当前信号屏蔽字的信号(逻辑或)
    • SIG_UNBLOCK:set包含了我们希望从当前信号屏蔽字中解除阻塞的信号(逻辑与非)
    • SIG_SETMASK:设置当前信号屏蔽字为set所指向的值(直接赋值)
  • set
    • 要操作的信号集,(为NULL则忽略)
  • oldset
    • 保存旧的信号掩码(可为NULL)

返回值:成功返回 0,失败返回 -1(设置 errno

  • 阻塞:信号暂存到未决信号集直到解除阻塞
  • 忽略:直接丢弃

2.3.3 sigpending获取未决信号集

如果某进程接受了一个该进程正在阻塞的信号,那么会将该信号填加到进程的等待信号集中。当之后解除了对该信号的锁定时,会随之将信号传递给此进程。

#include <signal.h>
int sigpending(sigset_t *set);

作用: 返回处于等待状态的信号集,并将其置于 set指向的sigset_t 结构中。


2.3.4 sigaction() - 设置信号处理
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
  • signum : 目标信号

  • act 新的信号处理方式

    • sa_handler:信号处理函数指针(或 SIG_IGNSIG_DFL)。
    • sa_mask:处理该信号时额外阻塞的信号集。
    • sa_flags:控制选项(如 SA_RESTARTSA_NODEFER
    • NULL
  • oldact

    • 保存旧的处理配置(可为NULL)

返回值:成功返回 0,失败返回 -1(设置 errno

struct sigaction {void     (*sa_handler)(int);          // 简单处理函数void     (*sa_sigaction)(int, siginfo_t *, void *); // 高级处理函数sigset_t sa_mask;                     // 处理期间屏蔽的信号集int      sa_flags;                    // 控制标志void     (*sa_restorer)(void);        // 内部使用(已废弃)
};

现在我们使用sigprocmask函数和sigpending函数完成一个函数。思路是

  1. 对2号信号写入信号集
  2. 将该信号集使用sigprocmask函数将2号信号block住
  3. 我们键盘输入ctrl+c,产生2号信号,发送至该进程。
  4. 使用sigpending函数输出pending位图,
    因为我们将2号进程block住了,该信号并不能抵达。我们再向其发送2号信号,信号被block住了并不会影响信号的写入。因此我们再发送2号进程之前pending位图应该全为0,发送2号进程之后会看见pending位图发送由01的变化。

执行流程:

  1. 前 5 秒内,SIGINT(Ctrl+C)被阻塞,信号进入未决状态但不触发处理。
  2. 5 秒后解除阻塞,若之前有未决的 SIGINT,会立即触发 handle 函数。
#include <iostream>
#include <cassert>
#include <unistd.h>
#include <signal.h>
using namespace std;
static void handler(int signo){cout << signo << " 号信号确实递达了" << endl;//最终不退出进程
}void DisplayPending(const sigset_t pending){// 打印 pending 表int i = 1;while (i < 32){if (sigismember(&pending, i))  cout << "1";else cout << "0";i++;} cout << endl;
}
int main(){// 更改 2 号信号的执行动作signal(2, handler);// 创建信号集sigset_t set, oset;// 信号集清空  0sigemptyset(&set);sigemptyset(&oset);sigaddset(&set, 2);	//将2号信号写入set// 设置当前进程的屏蔽信号集sigprocmask(SIG_BLOCK, &set, &oset);//0给进程// 死循环int n = 0;while (true){if (n == 5){// 采用 SIG_SETMASK 的方式,覆盖进程的 block 表sigprocmask(SIG_SETMASK, &oset, NULL); // 不接收进程的 block 表}// 获取进程的 未决信号集sigset_t pending;sigemptyset(&pending);int ret = sigpending(&pending);assert(ret == 0);(void)ret; // 避免 release 模式中出错DisplayPending(pending);n++;sleep(1);}return 0;
}

03. 信号处理

loading…


http://www.hkcw.cn/article/tWYWIlCnQJ.shtml

相关文章

庖丁解牛BLIP2

庖丁解牛BLIP2 更好的阅读体验&#xff0c;欢迎访问 庖丁解牛BLIP2 获得 论文: https://arxiv.org/abs/2301.12597 代码: https://github.com/salesforce/LAVIS/tree/main/projects/blip2 背景 多模态模型在过往发展的过程中&#xff0c;曾有一段时期一直在追求更大的网络架构…

中国女排世界联赛北京站名单出炉 18名运动员备战

2025世界女排联赛北京站将于6月4日至8日在北京国家体育馆举行,参赛队伍包括中国、土耳其、波兰、比利时、泰国和法国。中国排协于6月2日公布了参加北京站比赛的中国女排名单,共有18名运动员。主攻位置有吴梦洁、庄宇珊、唐欣、董禹含;副攻位置有王媛媛、万梓玥、单琳倩、陈厚…

乌克兰摧毁41架俄军战略轰炸机 乌方称“蛛网”行动成功

乌克兰安全局内部人士透露,代号“蛛网”的特别行动历时18个月的策划和实施,成功摧毁了41架俄军战略轰炸机。此次行动由泽连斯基亲自协调,安全局局长马柳克率队直接执行。知情人士称,该行动在后勤保障方面极具挑战性,包括通过秘密渠道向俄境内输送FPV无人机,并转运移动木制…

张家界溶洞垃圾堆7层楼高 谁该脸红 多年排污为何无人察觉

近日,有博主发布视频称张家界市慈利县一处天然溶洞遭人为排污,导致宝贵的溶洞变成“粪坑”。视频显示,溶洞内出现黄绿色液体。该溶洞位于通津铺镇长峪铺村杨家坡,系喀斯特地貌,垂直深度约150米,洞内存有陈年垃圾和污水,近期因暴雨导致洞内污水上涨外溢入溇水。据拍摄的网…

中国代表香会反驳对华无端指责 坚决抵制煽动对抗

针对美西方等个别国家在新加坡香格里拉对话会上对中国的无端指责,中国人民解放军国防大学代表团团长胡钢锋表示,不接受对中方的无端指责,有关内容无中生有,煽动对抗,企图搞乱亚太,不得人心,也不可能得逞。责任编辑:zhangxiaohua

河南七旬老人捡烟花被崩伤 意外引发广泛关注

5月31日,河南平顶山鲁山县发生一起意外事件,一位7旬老人在捡拾烟花筒时头部被崩伤。此事被目击者拍摄并上传网络后引起广泛关注。老人的亲属杨先生透露,医生表示老人右眼无法保住,脑部也受了伤,后续治疗费用预计近10万元。目前,老人仍在鲁山县人民医院重症监护室接受观察…

三层交换机模拟搭建实际网络实验

1、某企业&#xff0c;下有5个部门&#xff0c;分别是市场部16人、财务部22人、生产部110人、研发部24人、行政部28人门。现向运营商申请了一段ip地址&#xff1a;100.xxx.1.0/24&#xff08;XXX 为学生学号中的唯一标识部分&#xff09;&#xff0c;如果你是该公司的网管&…

在哈佛毕业礼演讲的中国女孩谈古诗 传递多元包容理念

中国女孩江玉蓉在哈佛毕业典礼上发表演讲,传递多元包容理念。当地时间5月29日,她在哈佛大学的毕业典礼上作为毕业生代表之一发言,引起广泛关注。江玉蓉来自中国青岛的一个普通家庭,通过不懈努力和自身天赋,获得了威尔士卡迪夫一所高中的全额奖学金,并在杜克大学完成了本科…

Baklib赋能企业内容中台构建

Baklib构建内容中台路径 Baklib作为智能内容管理工具&#xff0c;通过多终端适配系统将企业分散的知识资产进行云端聚合&#xff0c;形成统一的内容资源池。其用户需求分析引擎可深度解析访问行为数据&#xff0c;帮助企业快速定位核心知识模块&#xff0c;例如产品文档、培训…

美防长香会炒“中国威胁”有何企图 转移负面舆情

美国国防部长赫格塞思于5月31日在新加坡参加香格里拉对话会时发表讲话,极力渲染所谓“中国威胁”,以推动盟国增加军费开支。分析人士认为,赫格塞思此举可能是为了转移外界对群聊泄密事件等负面舆情的关注。对于赫格塞思的涉华消极言论,中国外交部发言人回应称,台湾问题纯属…

恶意软件清理工具,让Mac电脑安全更简单

​你的Mac最近是不是开始表演"电子迷惑行为"&#xff1f;浏览器主页突然变成澳门赌场&#xff0c;风扇转得比直升机螺旋桨还猛......恭喜你&#xff01;可能中奖获得"恶意软件大礼包"&#xff01;别慌&#xff0c;今天就教你用恶意软件清理工具化身数字特工…

Python-14(异常)

处理异常 try-except语句 该语句用来捕获异常。引发异常后的操作是执行except语句的异常处理代码&#xff0c;而不是直接抛出一段红色的输出。如果try语句没有检测到异常&#xff0c;那么就不会执行except中的内容。 try: 检测范围 except[expression[as identifier]]: 异常…

黄金消费新趋势:小克重产品受青睐 以旧换新业务升温 金价波动影响消费选择

近期国际金价波动加剧,面对这种变化,黄金消费市场也出现了新的趋势。在北京的一家珠宝城,柜台前聚集了不少顾客,他们正在挑选和询价。由于近期国际金价高位震荡,首饰金价单日波动可达几元到几十元不等,消费者更倾向于购买克重较小的产品,以减少金价波动带来的风险。与此…

学者谈马斯克:退隐智慧很艺术 政坛影响力难减

川普的一句俏皮话揭示了全球首富马斯克在政坛的影响力。上周三,美国前总统川普在与南非总统会晤时,突然指着场边的科技大咖开玩笑说:“瞧见没,埃隆可是南非老乡。我可不敢随便使唤他,分分钟能给你整出个大新闻。”这场景颇具戏剧性,因为就在前一天,特斯拉掌门人马斯克还…

马斯克跨界玩政治是被当枪使了吗 改革蓝图成泡影

埃隆马斯克,这位颠覆多个行业的传奇人物,将目光投向了效率低下的美国政府,想用科技和商业思维进行一场大改造。他雄心勃勃地提出成立“政府效率部”。然而,在华盛顿的政治引力场中,他的改革蓝图很快被金钱和权力的黑洞吞噬。呈现在他面前的不是政府的高效运转,而是一份增…

沃尔沃汽车在美国暂停生产 供应链中断影响

6月1日,沃尔沃汽车暂停了其位于美国南卡罗来纳州里奇维尔的装配厂生产,原因是汽车行业供应链持续中断,导致关键零部件短缺。里奇维尔工厂主要负责生产纯电动沃尔沃EX90,是沃尔沃在美国电气化战略中的重要支柱。近期贸易紧张局势加剧了全球供应链中断问题。美国对汽车行业进…

特殊家庭长期高空抛物该怎么管 特事特办解难题

高空抛物是违法行为,情节严重的还可能构成犯罪。广州市天河区棠德花苑小区的一对疑似精神状态不佳的母女在过去一年多的时间里经常从九楼家中高空抛物。尽管居委会和物业公司多次劝阻无效,只能提醒居民出行注意安全,但面对不可预料的高空抛物可能造成的危险,小区居民不得不…

美国东南部发生大规模枪击事件 1死11伤震动社区

美国北卡罗来纳州一社区在当地时间周日凌晨发生大规模枪击事件,导致1人死亡、11人受伤。警长办公室通报称,共有12名受害者,其中1人已经死亡,另1人伤势危急,多人正在住院治疗。目前尚未有涉案人员被捕。卡托巴县警长办公室、希科里市警察局以及北卡罗来纳州调查局特工正联合…

摄影师在西藏拍到红色精灵闪电 大自然的神秘杰作

5月31日至6月1日,中国摄影师在西藏山南捕捉到了罕见的红色精灵闪电,展示了大自然神秘的一面。这种闪电形成于大气中间层,是雷击产生电磁波的结果。它如同宇宙中的短暂访客,在空中存在的时间极短,往往在人们反应过来之前就已消失,成为自然界中最难拍摄的现象之一。红色精灵…

端午里的中国活力 传统文化走向世界

5月31日正值端午节,刚果(布)的青年与孔子学院师生共同参与包粽子活动,体验中国传统节日的独特魅力。一位名叫龙田中的学生表示,这是他第一次参加这样的活动,感觉非常奇妙,并计划将包好的粽子与同学们分享。另一位学生遂愿则说:“粽子很好吃,粽香飘进我的心。”同一天,…