1、信号的基本概念
信号是系统响应某个条件而产生的事件,进程接收到信号会执行相应的操作;
与信号有关的系统调用在<signal.h>头文件中有声明。
(1)常见信号的值及其对应功能说明:
(2)信号值在系统源码中的定义
#define SIGHUP 1
#define SIGINT 2 //键盘按下 Ctrl+c 时,会产生该信号
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#define SIGBUS 7
#define SIGFPE 8
#define SIGKILL 9 //该信号的响应方式不允许改变
#define SIGPIPE 13 //读端关闭的描述符,写端写入时产生,该信号会终止程序
#define SIGTERM 15 //系统 kill 命令默认发送的信号
#define SIGCHLD 17 //子进程结束后,会默认给父进程发送该信号
(3)信号的响应方式
- 默认:SIG_DFL
- 忽略:SIG_IGN
- 自定义:自定义的信号处理函数
2、信号的使用
修改信号的响应方式—signal()
在键盘上按下ctrl+c时,会给当前终端前台执行的进程发送SIGINT信号
使用signal修改SIGINT信号的响应方式示例代码如下:
#include<stdio.h>
#include<stdllib.h>
#include<unistd.h>
#include<assert.h>
#include<string.h>
#include<signal.h>
void fun(int sign)
{
printf("fun was called,sign=%d\n",sign);
}
int main()
{
//将函数作为参数,并没有调用fun
//只是作为声明,如果收到信号,则调用fun函数
sign(SIGINT,fun);
//循环输出
while(1)
{
sleep(1);
printf("main running\n");
}
exit(0);
}
运行截图
3、发送信号-kill()
kill()可以向指定的进程发送指定的信号:
int kill(pid_t pid,int sig);
- pid>0 指定将信号发送到某个进程
- pid==0 信号被发送到和当前进程在同一个进程组的进程
- pid==-1 将信号发送给系统上有权限发送的所有的进程
- pid<-1 将信号发送给进程组id等于pid绝对值,并且有权限发送的所有的进程
- sig 指定发送信号的类型
自定义实现结束进程的kill命令
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<assert.h>
6 #include<signal.h>
7
8 // 参数列表:./mykill 4566 9
9 int main(int argc,char* argv[])
10 {
11 //判断argc的参数个数,如果小于三个则退出
12 if(argc!=3)
13 {
14 printf("argc error\n");
15 return 0;
16 }
17 //将输入参数转换为整形变量
18
19 int pid=0;
20 int sig=0;
21 //sscanf()函数将数组内的数据以%d的形式赋值给pid
22 sscanf(argv[1],"%d",&pid);
23 sscanf(argv[2],"%d",&sig);
24
25 //判断kill()命令是否实现成功
26 //给pid所对应进程发送sig信号
27 if(kill(pid,sig) == -1)
28 {
29 perror("kill error\n");
30 }
31 exit(0);
32 }
运行截图:
(1) 运行等待进程
(2)查看sleep进程的pid
(3)编译运行mykill.c文件
(4)sleep进程结束
通过系统的默认指令kill也能够终止进程
信号9 代表强制结束的信号,不允许改变和忽略
信号15结束当前程序,kill默认发送的信号
结果: