Linux:39内核与用户--信号-lesson28(待)-未完

发布于:2025-04-14 ⋅ 阅读:(25) ⋅ 点赞:(0)

捕捉信号的另一种方法,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分钟方案一和方案二 


网站公告

今日签到

点亮在社区的每一天
去签到