作者主页: 作者主页
本篇博客专栏:Linux
创作时间 :2024年11月12日
信号和信号量
首先说明这两者之间没有任何关系
信号:信号是在软件层次对中断机制的一种模拟,是一种异步通知机制,用于通知进程发生了某个特定的事件,例如当用按下Ctrl+c时,会产生一个SIGINT信号发送给当前正在运行的进程,通知他用户想要进行中断操作。信号既可以由操作系统内核发送给进程,也可以由进程发送给进程(需要一定的权限)
信号量:信号量是一种用于进程同步和互斥的机制,用于协调多个进程或者线程对共享资源的访问。它本质上就是一个计数器,用于控制同时访问共享资源的进程或线程的数量。信号量表示当前可用资源的数量。
信号
我们可以通过kill -l来查看所有的信号。
信号的处理
信号处理有三种情况:
- 默认动作
- 忽略动作
- 自定义处理——信号的捕捉
信号捕捉
signal
信号的产生
信号产生的方式:
- 通过kill命令,向指定进程发送命令
- 键盘可以产生信号,Ctrl+c(SIGINT),Ctrl+\(SIGQUIT)
- 系统调用
- 软件条件
- 异常
系统调用
kill
通过运行下面这个代码,得到这个进程的pid,然后通过我们自己写的Mykill来执行对应的信号,实现对应的操作
raise
这个就是我们通过raise不断给自己发送3号信号,然后signal捕捉执行
abort
执行上述代码之后,一秒之后我们的进程就结束了,这是为什么呢?
其实abort就相当于我们的6号信号,6号信号(SIGABRT)就是终止我们的进程,即使我们自定义捕捉了这个信号,也会执行一次自定义的函数之后结束,所以这个是比较特殊的一个
由软件产生信号
SIGPIPE是一种由软件条件产生的信号。下面介绍alarm函数和SIGALRM信号。
alarm
如果我们稍微改一下代码,像这样
硬件异常产生信号
运行这段代码会直接崩溃,因为这里涉及到了除零操作,这是不允许的,还有就是野指针也会出现出错,除以0会发送8号信号(SIGFPE),野指针会发送11号信号(SIGSEGV)
此时我们如果将8号或者11号信号捕捉,就会死循环打印对应的东西
Core、Term
默认下这个功能是关闭的,我们可以这样打开
指令 ulimit -a 可以查看系统中对于普通用户能使用资源对应的限制。下面可以看到core file size 大小是0,所以云服务器默认不允许我们形成core文件。
通过ulimit -c 数字 指令,这样core file选项就打开了。此时再运行程序,就有core文件了。
我们把Makefile文件里g++带上-g选项,允许被调试。
当程序里面有除0错误时,并且有了core文件。我们gdb进行调试。 输入 core-file core 给gdb加载core文件,我们就可以直接定位到程序出错的地方。
所以core是协助我们进行debug的文件,这种操作也叫事后调试
阻塞信号
信号相关其他常见概念
- 实际执行信号的处理动作叫做信号递达 (Delivery)
- 信号从产生到递达之间的状态叫做信号未决,即Pending状态
- 进程可以选择阻塞(Block)某个信号,阻塞和有没有未决没有关系
- 被阻塞的信号产生时将处于未决状态,知道进程接触对此信号的阻塞,才进行递达动作
- 注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略实在递达之后可以选择的一种处理动作
在内核中表示
sigset_t
信号集操作函数
sigset_t类型内部如何存储这些bit依赖于系统实现,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset_ t变量
sigprocmask
sigpending
捕捉信号
内核如何实现信号的捕捉
再谈地址空间
sigaction
volatile
可以通过gcc main.cc -01对gcc进行优化
优化后,发现按ctrl+c 程序不会结束。因为main执行流判定代码里没有对gflag进行修改,觉得不用每次都从内存拿数据,直接在第一次拿的时候,把gflag的值优化到寄存器里,从此之后,每次while检测只检测寄存器里的值。当收到信号后修改gflag的值,修改的是内存里的gflag,就导致寄存器隐藏了内存中的真实值。这是编译器过度优化导致的问题。
为了保持内存的可见性,就有了volatile关键字。
SIGCHLD信号
wait和waitpid函数清理僵尸进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进 程结束等待清理(也就是轮询的方式)。采用第一种方式,父进程阻塞了就不能处理自己的工作了;采用第二种方式,父进程在处理自己的工作的同时还要记得时不时地轮询一下,程序实现复杂。
最后:
十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:
1.一个冷知识:
屏蔽力是一个人最顶级的能力,任何消耗你的人和事,多看一眼都是你的不对。
2.你不用变得很外向,内向挺好的,但需要你发言的时候,一定要勇敢。
正所谓:君子可内敛不可懦弱,面不公可起而论之。
3.成年人的世界,只筛选,不教育。
4.自律不是6点起床,7点准时学习,而是不管别人怎么说怎么看,你也会坚持去做,绝不打乱自己的节奏,是一种自我的恒心。
5.你开始炫耀自己,往往都是灾难的开始,就像老子在《道德经》里写到:光而不耀,静水流深。
最后如果觉得我写的还不错,请不要忘记点赞✌,收藏✌,加关注✌哦(。・ω・。)
愿我们一起加油,奔向更美好的未来,愿我们从懵懵懂懂的一枚菜鸟逐渐成为大佬。加油,为自己点赞!