捕捉信号的另一种方法,sigaction:

捕捉信号的另一种方法。
sigaction:
你想如何处理信号,如何处理自定义捕捉方法。
参数:
(1)
(2)
sigset_t sa_mask,信号集
代码验证:
正在处理某个信号,该信号不会被递达,再次收到该信号,不再接收。
不让同一个信号被高频递达,只可以依次抵达。
验证
“把sa.mask和sa.flag”清空,不然会对结果有影响
handle里面加上循环,打印pending表,
看再次输入相同信号时,pending是否会出现0 ->1
结果
再次的2号新号无法递达,被屏蔽了
添加3,4号,表示屏蔽2号的同时,把3,4号也同时都屏蔽了
可重入函数
main执行流和handler执行流,冲突
刚把p->next = head,被中断,又插入一个,会在成内存泄漏
无影响:可重入
有影响:不可重入
大部分函数都是不可重入的。
全局变量:不可重入
函数,临时变量 -- 可重入
调⽤了malloc或free,因为malloc也是⽤全局链表来管理堆的。
• 调⽤了标准I/O库函数。标准I/O库的很多实现都以不可重⼊的⽅式使⽤全局数据结构。
volatile:c语言关键字
volatile
是一种类型修饰符,用于修饰变量,告诉编译器这个变量可能会被程序之外的其他因素(如硬件设备、其他线程等)改变,因此编译器不能对它进行优化,每次访问该变量时都要从内存中读取最新的值。作用:
防止编译器优化:在多线程环境下,如果一个变量被多个线程共享且会被线程修改,使用
volatile
可以避免编译器对变量访问的优化,确保每次读取的都是变量的最新值。硬件交互:在嵌入式系统中,某些内存地址可能映射到硬件设备的寄存器,这些寄存器的值可能会被硬件改变。使用
volatile
可以保证每次访问这些地址时都能读取到硬件写入的最新值。使用场景:
多线程共享变量:例如在 Java 中,一个线程修改了某个变量的值,而其他线程需要及时获取这个变量的最新值,就可以将该变量声明为
volatile
。硬件设备寄存器访问:在 C 或 C++ 的嵌入式开发中,访问硬件设备的寄存器时,通常会将映射到寄存器的变量声明为
volatile
。
测试用例
符合预期,正常修改并退出
-o,修改优化级别。
默认优化,-o0,不做优化
-o1
为什么,更改不终止了呢???
在o1优化里,只查寄存器,0,修改外面的flag不做修改,所以就一直循环,不做退出
用volatile优化,使得flag不做优化,不会再存放在寄存器里面。保证每次都从内存里面的flag拿,而不是取查寄存器。
![]()
进行优化,寄存器会覆盖变量的变化情况,内存不可见了。
SIGCHLD信号
17号信号
子进程退出时,会给父进程发送17号信号,但是被忽略了,所以我们看不到
测试用例
![]()
子进程退出,给父进程发送17号信号,√
多个子进程
方案一
WNOHANG
任意多个进程的回收
代码
监控脚本
方案二
就会自动帮我们回收
就不用再等待子进程了。
把子进程自动回收。
问题
默认动作是SIG_IGN,为什么还要自定义呢???
signal(SIGCHLD,SIG_DFL).
DFL:默认。
子进程给父进程发送,SIG_CHLD,父进程处理用的是缺省 的ign
如果不理解可以认为:两种是不一样的
系统默认->僵尸
手动默认->可以做到
后面的20分钟方案一和方案二