1. 概念
linux系统支持的所有信号均定义在/usr/include/asm/signal.h,其中常见的信号有:
- SIGNKILL:杀死进程
- SIGSTOP:暂停进程
- SIGCHLD:子进程停止或结束时用来通知父进程
2. 发送信号
2.1 函数原型
#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);
kill函数将信号发送给进程或进程组。
raise函数允许进程向自身发送信号。
2.2 返回值
成功返回0,失败返回-1
2.3 参数
pid参数有4种情况:
- pid > 0 : 将该信号发送给进程ID为pid的进程;(具体pid的进程)
- pid = 0 : 将该信号发送给与发送进程属于同一进程组的所有进程(这些进程的进程组ID等于发送进程的进程组ID),而且发送进程具备向这些进程发送信号的权限。(同组进程)
- pid < 0 : 将该信号发送给其进程组ID等于pid的绝对值,而且发送进程具有向其发送信号的权限。(绝对值为pid的进程组)
- pid = -1 : 将该信号发送给发送进程有权限向他们发送信号的系统上的所有进程。(所有进程)
signo :指明要发送的信号
3. 处理信号
3.1 函数原型
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
设置信号的处理方式。
3.2 返回值
成功处理函数指针,失败返回SIG_ERR
3.3 参数
signum:指明要处理的信号
handler:对应信号的处理方式,一般有3种:
- SIG_IGN:忽略信号
- SIG_DFL:交给内核处理
- 用户自定义函数:交给用户自定义的函数处理
4. 示例
进程b:pb.c
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
void func()
{
printf("signal receive succeed!\n");
}
void main()
{
//等待接收SIGINT信号,如收到执行回调函数func
signal(SIGINT, func);
pause();
}
编译运行:
[root@192 signal]# gcc pb.c -o pb
[root@192 signal]# ./pb
此时b进程由于未收到信号,会一直阻塞。
进程a:pa.c
#include <signal.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[])
{
//进程号
pid_t pid = atoi(argv[1]);
//发送信号
kill(pid, SIGINT);
}
编译运行:
[root@192 signal]# gcc pa.c -o pa
[root@192 signal]# ps -aux | grep pb
root 2126 0.0 0.0 4212 352 pts/0 S+ 18:53 0:00 ./pb
root 2135 0.0 0.0 112824 980 pts/1 S+ 18:55 0:00 grep --color=auto pb
[root@192 signal]# ./pa 2126
[root@192 signal]#
通过ps查找到进程pb的进程号,执行进程pa。
此时pb进程打印如下:
[root@192 signal]# ./pb
signal receive succeed!
[root@192 signal]#