参考:《UNIX环境高级编程》
1、信号的概念:
信号是软件中断。很多比较重要的应用程序都需处理信号。信号提供了一种处理异步事件的方法。
每个信号都有一个名字,这些名字都以三个字符SIG开头;
2、信号处理流程
1)选择信号;
2)发送信号;
3)处理信号:忽略信号;交给内核处理;用户自定义处理方法;
3、信号类型:
Linux系统支持的所有信号均定义在 /usr/include/asm/signal.h(展示),其中常见的信号有:
SIGINT:当用户按中断键(一般是DELETE或Ctrl+C)时,终端驱动程序产生此信号并送至前台进程组中的每一个进程。当一个进程在运行时失控,特别是它正在屏幕上产生大量不需要的输出时,常用此信号终止它;
SIGKILL:杀死进程;
SIGSTOP:暂停进程;
SIGHOLD:子进程停止或结束时用来通知父进程;
4、发送信号kill
函数原型:
int kill(pid_t pid, int sig);
函数功能:
该系统调用可以用来向任何进程或进程组发送任何信号。参数pid的值为信号的接收进程
头文件
#include <sys/types.h>
#include <signal.h>
返回值:
成功返回0,失败返回-1;
该调用执行成功时,返回值为0;错误时,返回-1,并设置相应的错误代码errno。下面是一些可能返回的错误代码:
EINVAL:指定的信号sig无效。
ESRCH:参数pid指定的进程或进程组不存在。注意,在进程表项中存在的进程,可能是一个还没有被wait收回,但已经终止执行的僵尸进程。
EPERM:进程没有权力将这个信号发送到指定接收信号的进程。因为,一个进程被允许将信号发送到进程pid时,必须拥有root权力,或者是发出调用的进程的UID 或EUID与指定接收的进程的UID或保存用户ID(savedset-user-ID)相同。如果参数pid小于-1,即该信号发送给一个组,则该错误表示组中有成员进程不能接收该信号。
参数说明:
1)pid
pid>0 进程ID为pid的进程
pid=0 同一个进程组的进程
pid<0 pid!=-1 进程组ID为 -pid的所有进程
pid=-1 除发送进程自身外,所有进程ID大于1的进程
2)sig:指明要发送的信号;
sig是信号值,当为0时(即空信号),实际不发送任何信号,但照常进行错误检查,因此,可用于检查目标进程是否存在,以及当前进程是否具有向目标发送信号的权限(root权限的进程可以向任何进程发送信号,非root权限的进程只能向属于同一个session或者同一个用户的进程发送信号)。
5、处理信号signal
函数原型:
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
函数功能:
设置信号的处理方式;
头文件
#include <signal.h>
返回值:
成功返回处理函数的指针,失败返回SIG_ERR;
参数说明:
signum:指明要处理的信号;
handler:对应信号的处理方式,取值如下
SIG_IGN:忽略信号;
SIG_DFL:交给内核来处理,按照linux默认的方式进行处理;
用户自定义函数:用户自定义处理方式;
6、代码
/*
B进程
1)设置进程处理方式;
2)等待信号(pause()函数的功能是使调用进程挂起,直至捕捉到一个信号);
*/
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
/* 自定义信号处理函数 */
void myfunc(int a)
{
printf("Process B received SIGINT\n");
}
void main()
{
signal(SIGINT, myfunc);
pause();
}
/*
A进程:
发送信号给B进程;
*/
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
void main(int argc, char *argv[])
{
pid_t pid;
pid = atoi(argv[1]);
kill(pid, SIGINT);
}
发送命令验证:
1)在终端1中,输入./bprocess命令运行bprocess进程;
2)新开一个终端2,输入ps -aux | grep bprocess命令找到bprocess进程的进程号9083;
3)终端2中输入kill -n SIGINT B进程号,如kill -n SIGINT 9083;
4)在终端1中查看bprocess进程打印信息;
test$ ./bprocess
Process B received SIGINT
test$
运行aprocess进程验证:
1)在终端1中,输入./bprocess命令运行bprocess进程;
2)新开一个终端2,输入ps -aux | grep bprocess命令找到bprocess进程的进程号9127;
3)终端2中输入./aprocess 9127;
4)在终端1中查看bprocess进程打印信息;
test$ ./bprocess
Process B received SIGINT
test$