摘要: 总结了信号处理流程,信号种类,以及信号处理函数,最后给出一个实例加深理解。
一、信号处理流程
信号是Linux当中一种很古老的进程间的通信机制,通信的流程为:
第一步:进程A选择信号;
第二步:进程A发送信号;
第三步:进程B处理信号。
二、信号种类
Linux当中的信号类型有很多种,目前应该是有63种,前31种不支持排队,是非实时信号,后33种是扩充的实时信号,前31种可以查看/usr/include/asm/signal.h。常见的信号列出如下:
SIGKILL:杀死进程
SIGSTOP:暂停进程
SIGCHLD:子进程停止或结束时用来通知父进程。
SIGINT:当键盘按下CTRL+C从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操作是中断 (INTERRUPT) 该进程。
SIGQUIT:当键盘按下CTRL+\从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操作是退出 (QUIT) 该进程。
SIGTSTP:当键盘按下CTRL+Z从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操作是暂停 (STOP) 该进程。
SIGCONT:用于通知暂停的进程继续。
SIGALRM:起到定时器的作用,通常是程序在一定的时间之后才生成该信号。
三、信号处理函数
1.发送信号
int kill(pid_t pid,int sig)
函数作用:向一个进程发送信号
头文件:include <sys/types.h> include <signal.h>
返回值:成功返回0,失败返回-1
函数参数:
pid情况比较多:
pid>0将信号传给进程识别码为pid 的进程。
pid=0 将信号传给和目前进程相同进程组的所有进程。
pid=-1 将信号广播传送给系统内所有的进程。
pid<0 将信号传给进程组识别码为pid绝对值的所有进程。
sig:
各种信号的编号。
2.处理信号
typedef void(*sighandler_t)(int)
sighandler_tsignal(int signum,sighandler_t handler)
函数作用:设置信号的处理方式
头文件:include <signal.h>
返回值:成功返回处理函数的指针,失败返回SIG_ERR
函数参数:
signum:要处理的信号
handler:按照handler的方式来处理信号,handler实际上是一个函数指针,有三种取值:SIG_IGN忽略该信号,SIG_DFL:交给内核去处理,用户自定义的处理方式。
四、实例
使用进程A给进程B发送一个信号,进程B使用自己定义的信号处理函数进程回应。
<span style="font-size:18px;">进程B:bprocess.c
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
void myfunc(int a)
{
printf("Ihave received the signal!\n");
}
int main(void)
{
signal(SIGINT,myfunc);
pause();
return0;
}</span>
这部分就是利用信号处理函数signal,第一个是要处理的信号,第二个参数是我们定义的处理函数,类型为void,带有一个int参数,我们在处理函数里面就打印一句话,便是已经接收到了信号并处理。
<span style="font-size:18px;">进程A:aprocess.c
#include <sys/types.h>
#include <stdio.h>
#include <signal.h>
int main(int argc,char* argv[])
{
pid_tpid;
pid=atoi(argv[1]);
kill(pid,SIGINT);
return0;
}</span>
A,B都编译好之后,先运行B进程,然后使用#ps aux查看B的进程号,我这里是5841,然后利用主函数的第一个参数存放pid号传进去,这里的atoi函数是将字符串转化成整形的一个函数,pid是一个整形类型,而我们的argv[]是字符串类型的,所以需要转换。运行起来之后就可以看到B本来从暂停状态打印出了I have received the signal!
这篇帖子就总结到这里吧,如有不正确的地方还请指出,大家共同进步!