全文约 3036 字,预计阅读时长: 9分钟
信号
- 信号是进程之间事件异步通知的一种方式,属于软中断。过程:信号产生,信号识别,处理处理。
- 每个信号都有一个编号和一个宏定义名称,这些宏定义可以在
signal.h
中找到,例如其中有定义#define SIGINT 2
Ctrl-C
产生的信号只能发给前台进程。 Shell可以同时运行一个前台进程和任意多个后台进程,- 一个命令后面加个
&
可以放到后台运行,这样Shell不必等待进程结束就可以接受新的命令,启动新的进程。
- 前台进程在运行过程中用户随时可能按下 Ctrl-C 而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到 SIGINT 信号而终止,所以信号相对于进程的控制流程来说是异步(Asynchronous)的。
- 对于相当一部分信号而言,当进程收到的时候,默认的处理动作是终止当前进程。
- 对进程而言,有一些信号不能被捕捉和忽略,如:
kill -9
- 进程收到信号,不是立即处理的,而是在合适的时候。
- 对进程而言,有一些信号不能被捕捉和忽略,如:
- 信号的处理:
- 默认方式(部分终止进程,部分有特定的功能)
- 忽略信号
- 自定义方式:捕捉信号
- 站在语言角度:程序崩溃;站在系统角度,进程受到了信号。
信号发送
- 信号的产生有如下的方式:
- kill 命令产生
kill -l
1—31普通信号;34—64实时信号,响应要求级别特别强的信号,一旦发出进程必须响应。 - 键盘产生
- 由软件条件产生信号:闹钟
- 程序异常 、硬件异常产生
- 当你的进程触发错误时,基本都有对应的软硬件监控,cpu下的状态寄存器,内存和页表mmu等,会被OS识别到,然后给目标进程发送信号,来达到终止进程的目的。
- kill 命令产生
- 信号的产生,在进程的运行的任何时间点都可以产生,有可能进程正在做更重要的事情。
- 因为信号不是立即处理的,所以信号在进程的PCB里保存着。
- 对进程而言:是否有信号、是什么信号
- 存储方式:位图,无符号整形,1在比特位中的位置意味着是哪个信号,有没有1意味着有没有信号。
- 是谁发的,如何发;直接简介通过OS向进程发信号。
- 发送信号的本质,相当于写对应进程的PCB的位图。因为OS是进程的管理者,OS是由这个能力和义务的。
- 由软件条件产生信号:闹钟定时终止
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
//调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动作是终止当前进程。
----//一秒内可以加多少次。
int a =0;
void add(int signo)
{
cout<<signo<<endl;
cout<<a<<endl;
exit(1);
}
int main()
{
for(int i =1,i<32;i++)
{
signal(i,add);
}
alarm(1);
while(true)
{
a++;
}
return 0;
}
- 系统调用产生信号:
void abort(void);
int raise(int sig);
int kill(pid_t pid, int sig);
---//kill测试 kill 9 1231231
int main(int argc,char* argv[])
{
kill(atoi(argv[2]),atoi(argv[1]));
}
- MakeFile