一、信号的基本概念
1.基本信号对应的响应
信号是系统响应某个条件而产生的事件,进程接收到信号会执行相应的操作。
与信号有关的系统调用在“signal.h”头文件中有声明
常见信号的值,及对应的功能说明:
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 SIGUSR1 10
#define SIGSEGV 11
#define SIGUSR2 12
#define SIGPIPE 13 //读端关闭的描述符,写端写入时产生,该信
号会终止程序
#define SIGALRM 14
#define SIGTERM 15 //系统 kill 命令默认发送的信号
#define SIGSTKFLT 16
#define SIGCHLD 17 //子进程结束后,会默认给父进程发送该信
号
#define SIGCONT 18
#define SIGSTOP 19
#define SIGTSTP 20
#define SIGTTIN 21
#define SIGTTOU 22
#define SIGURG 23
二、信号响应方式的修改-signal()
1.signal()函数
sighandler_t是函数指针,函数原型为 void fun(int)
signum是信号值
sighandler_t signal(int signum, sighandler_t handler)就是当signum信号产生时,响应方式为回调函数handler的动作。
回调函数SIG_IGN是忽略信号,即不作任何响应,SIG_DFL是信号的响应方式为默认方式。
2.signal()函数的使用
我们长使用的Ctral+c就是触发了信号SIGINT(值为2),比如我们想要修改Ctral+c信号的响应方式:
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<string.h>
4 #include<signal.h>
5
6 void fun(int sig)//该函数的动作即为信号修改后的响应方式
7 {
8 printf("这是信号SIGINT(%d)的相应方式\n", sig);
9 }
10
11 int main()
12 {
13 signal(SIGINT, fun);//将Ctral+c(信号SIGINT)响应方式修改为回调函数fun的动作
14 while(1)
15 {
16 printf("main run\n");
17 sleep(1);
18 }
19 return 0;
20 }
运行结果:
可以修改其他信号的相应方式,只需要将signal中的第一个参数信号SIGINT修改为其他信号就可以了。
如果想要第一次修改Ctral+C的响应方式,第二次让它默认响应方式响应呢?上面说了SIG_DFL可以使信号的响应方式回复默认方式。
代码:
#include<stdio.h>
2 #include<unistd.h>
3 #include<string.h>
4 #include<signal.h>
5
6 void fun(int sig)
7 {
8 printf("这是信号SIGINT(%d)的相应方式\n", sig);
9 signal(SIGINT, SIG_DFL);//将Ctral+C(信号SIGINT)的响应方式改为默认方式
10 }
11
12 int main()
13 {
14 signal(SIGINT, fun);//将Ctral+C(信号SIGINT)响应方式改为回调函数fun的动作
15 while(1)
16 {
17 printf("main run\n");
18 sleep(1);
19 }
20 return 0;
21 }
~
运行结果:
三、发送信号-kill()
1.kill函数原型
成功返回0,失败返回-1.
参数pid是进程id, sig是信号,即给进程id为id的进程发送信号sig。
pid > 0 指定将信号发送个那个进程
pid == 0 信号被发送到和当前进程在同一个进程组的进程
pid == -1 将信号发送给系统上有权限发送的所有的进程
pid < -1 将信号发送给进程组 id 等于 pid 绝对值,并且有权限发送的所有的进程。
sig 指定发送信号的类型。
2.kill函数的使用
#include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <signal.h>
5
6 int main(int argn, char* argv[])
7 {
8 if(argn != 3)
9 {
10 printf("argc error\n");
11 exit(0);
12 }
13
14 int pid = 0;
15 int sig = 0;
16 sscanf(argv[1],"%d",&pid);
17 sscanf(argv[2],"%d",&sig);
18
19 if(kill(pid,sig) == -1)
20 {
21 perror("kill error");
22 }
23 exit(0);
24 }
下面运行一个程序,用自己写的kill命令结束其运行:
用自己的kill可执行文件向signal_SIGINT程序发送9号命令,将其杀死。