信号通讯
信号(signal)机制是UNIX系统中最为古老的进程间通信机制,有很多条件可以产生一个信号:
1、 当用户按某些按键时,产生信号。
2、 硬件异常产生信号:除数为零,无效的存储访问等等。这些信号通常有硬件检测得到,将其通知内核,然后内核产生适当的信号通知进程,例如: 内核对正在访问一个无效存储区的进程产生一个SIGSEGV信号。
3、进程用kill函数将信号发送给另一个进程。
4、 用户可以用kill命令将信号发送给其他进程。
信号类型
几种常见的信号
SIGHUP: 从终端发来的结束信号
SIGINT: 来自键盘的中断信号(ctrl+c)
SIGKILL: 该信号结束接收信号的进程
SIGTERM: KILL命令发出的信号
SIGCHLD: 表示子进程停止或结束的信号
SIGSTOP: 来自键盘(ctrl+Z)或调试程序的停止执行信号
信号处理
当某信号出现时,将按下面三种方式中的一种处理:
1、忽略此信号
大多数信号都是按这种方式处理的,但有两种信号不能被忽略。SIGKILL和SIGSTOP。这两种信号不能被忽略的原意是他们向超户提供了一种终止或停止进程的一种方法。
2、执行用户希望的动作
通知内核在某种信号发生时,调用一个用户函数。在用户函数中,执行用户希望的处理。
执行系统默认动作
对大多数信号的系统默认动作是终止该进程。
信号发送
发送信号的主要信号有kill和raise。
区别:
kill既可以向自身发送信号,也可以向其他进程发送信号。而raise函数是向进程自身发送信号。
#include(sys/types.h)
#include(signal.h)
int kill(pid_t pid,int signo)
int raise(int signo)
kill的pid参数有四种不同情况:
1、pid>0
将信号发送给进程ID为pid的进程。
2、pid==0
将信号发送给同组进程。
3、pid<0
将信号发送给其进程组ID等于pid绝对值得进程。
4、pid==-1
将信号发送给所有进程。
Alarm
使用alarm函数可以设置一个时间值(闹钟时间),当到达所设定的时间,产生SIGALRM 信号。如果不捕捉此信号,则默认动作是终止该进程。
#include<unistd.h>
insigned int alarm(unsigned int seconds)
Seconds:经历指定的秒数后会产生信号SIGALRM。
Pause
pause函数使调用函数挂起直至捕捉到一个信号。
#include<ubistd.h>
int pause(void)
只有执行了一个信号处理函数后,挂起才结束。
信号的处理
§当系统捕捉到某个信号时,可以忽略该信号或是使用指定的处理函数来处理该信号,或是使用系统默认的方式。
§§ 信号的处理方法主要有两种,一种是使用简单的signal函数,另一种是使用信号集函数组。
signal
#include<signal.h>
void(*signal(int signo,void(*func)(int)))(int)
//可以理解为
//typedef void(*sighandler_t)(int)
//sighandler_t signal(int signum,sighandler_t handler)
Func可能是:
1、SIG_IGN:忽略此信号
2、SIG_DEL:按系统默认方式处理
3、信号处理函数名:使用该函数处理
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
void my_func(int sign_no)
{
if (sign_no==SIGINT)
printf("i have get SIGINT\n");
else if(sign_no==SIGQUIT)
printf("i have get SIGQUIT\n");
}
int main()
{
printf("waiting for signal SIGINT or SIGQUIT\n");
/*注册信号处理函数*/
signal(SIGINT,my_func);
signal(SIGQUIT,my_func);
pause();
exit(0);
}
这里我们运行起程序之后用kill给进程发送信息。格式为:
kill -s 信息 pid
进程号可以用:ps aux 查看
例如我查的我的进程号为623 那么我的发送信息格式为:kill -s SIGQUIT 623
版权声明:本文为博主原创文章,未经博主允许不得转载。