信号的基本概念
- 信号是系统相应某个条件而产生的事件,进程接收到信号会执行相应的操作
- 与信号有关的系统调用在
signal.h
头文件中有声明 - 常见信号的值,及对应的功能说明:
通过对某个进程发送信号来告诉进程某个事件产生了,再由进程处理这个事件(举个例子:比如我们在上课,老师说下课这就是一个信号,然后我们都收拾东西开始回家这就属于对事件的处理)
再举个例子,比如我们现在运行一个sleep 300
,然后我们ctrl + c
,这个过程就是sleep进程收到我们的结束进程的信号,然后进行结束进程
进程可以通过获得内核或者其他进程的发送信号,然后来进行相应,并且可以通过设置相应的方式
信号的使用
- 设置信号的相应方式
signal()
- 默认
SIG_DFL
- 忽略
SIG_IGN
- 自定义:
void fun_sig(int sig)
我们通过帮助手册查看signal
方法
写一段代码来看看
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<signal.h>
void sig_fun(int sig)
{
printf("sig=%d\n",sig);
}
int main()
{
//SIGINT 就是 ctrl + c,假如收到SIGINT信号,就去调用这个函数
signal(SIGINT,sig_fun);
while(1)
{
printf("main run\n");
sleep(1);
}
}
当我们输入SIGINT
信号,内核就会去调用我们设置的方法
通过信号实现自己的KILL命令
查看帮助手册,我们是通过系统调用来实现
我们先看一下系统命令kill的使用,我们通过kill
命令来杀死创建的一个sleep
进程,这里使用kill
默认传送15号信号
假如这个sleep
被暂停挂起(对15号信号忽略),通过kill pid
就不能终止,需要加上参数-9
传送9号信号来进行杀死,9号信号不会被进程忽略,让管理员再任意情况都能进行进程终止
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<signal.h>
int main(int argc,char* argv[])//会传入参数
{
if(argc != 3 )// 1../mykill 2. pid 3. 信号 sig
{
printf("argc errno\n");//如果参数不正确
return 0;
}
int pid = 0;
int sig = 0;
sscanf(argv[1],"%d",&pid);//通过已有的参数,当作从键盘获得数据进行给予
sscanf(argv[2],"%d",&sig);
if(kill(pid,sig) == -1 )
{
perror("kill error");//kill失败
}
exit(0);
}
执行成功