一、信号
1、概念
- 在Linux中用于进程间通信和控制的一种机制,是进程之间事件异步通知的一种方式,属于软中断。
- 所有信号的产生,最终都要由OS来进行执行,因为OS是进程的管理者。
- 信号的处理可以不立即处理,而在合适的时候再处理。它有一个时间窗口,在这个时间窗口内,必须记住信号的到来。
- 尽管进程没有收到信号,它也要知道对合法信号的处理操作,这属于进程内置功能的一部分。
2、系统定义的信号列表

- 每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到。
- 编号34以下的信号为普通信号,编号34及以上的信号为实时信号。
- 信号 SIGKILL 和 SIGSTOP 无法被捕获或者忽略。
3、常见的信号处理方式
- SIG_IGN:忽略信号。
- SIG_DFL:执行信号的默认处理动作。
- 捕捉信号:提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数。
二、产生信号的方式
1、终端按键
(1)组合键
- Ctrl + c:信号2(SIGINT)。
- Ctrl + \:信号3(SIGQUIT)。
(2)示例代码
void handler(int signo)
{
cout << "get a signo: " << signo << endl;
}
int main()
{
for(int i = 1; i <= 31; ++i)
{
signal(i, handler);
}
while(true)
{
cout << "I am a crazy process" << " pid = " << getpid() << endl;
sleep(1);
}
return 0;
}
(3)运行结果


2、调用系统函数
(1)kill命令
(2)kill函数
【1】函数

【2】描述
- kill函数,即系统调用,可用于向任何进程或进程组发送任何信号。
- 如果 pid 为正数,则将 sig 信号发送到 pid 指定的进程。
- 如果 pid 等于 0,则 sig 信号将发送到调用进程的进程组中的每个进程。
- 如果 pid 等于 -1,则 sig 信号将发送到调用进程有权发送信号的每个进程,但进程1(init)除外。
- 如果 pid 小于 -1,则 sig 将发送到进程组中 ID 为 -pid 的每个进程。
- 如果 sig 为 0,则不发送信号,但仍执行错误检查。这可用于检查进程 ID 或进程组 ID 是否存在。
(3)raise函数
【1】函数

【2】描述
- raise函数向调用进程或线程发送 sig 信号。
- 在单线程程序中,它等价于 kill(getpid(), sig);
- 在多线程程序中,它等价于 pthread_kill(pthread_self(), sig);
- 如果信号有自定义的处理函数,则raise函数只有在该函数返回后才会返回。
(4)abort函数
【1】函数