信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。
信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了那些系统事件。
如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递个它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞取消时才被传递给进程。
信号的产生
1.用户在终端按下某些键时,终端驱动程序会发送信号给前台进程,例如ctr+c产生SIGINT, ctr + \产生SIGQUI信号,ctr + z产生SIGTSTP。
2.硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给当前进程 。
3.一个进程调用int kill(pid_t pid,int sig)函数可以给另一个进程发送信号
4.可以用kill命令给某个进程发送信号,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理动作是终止进程。
5.当内核检测到某种软件条件发生时也可以通过信号通知进程,例如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生SIGPIPE信号。
进程对信号的处理
1.忽略此信号
大多数信号都按照这种方式进行处理,担忧两种信号却决不能被忽略。它们是: SIGKILL 和 SIGSTOP。 这两种信号不能停止的原因是:它们向超级用户提供了一种终止或停止进程的方法。
2.执行用户希望的动作
通知内核在某种信号发生时,调用一个用户函数。在用户函数中,执行用户希望的处理。
3.执行系统默认动作
对大多数信号的系统默认动作是终止该进程。
信号相关API
int raise(int sig);
# 向自己发送信号
# sig : 信号的signum
int kill(pid_t pid, int sig);
# 向一个指定的进程发送信号
# 参数说明
# kill 的 pid 参数有4中不同的情况
# pid > 0 : 将信号发送给进程ID为pid的进程
# pid == 0 : 将信号发送给同组的进程
# pid < 0 : 将信号发送给其进程组 ID 等于 pid绝对值的进程
# pid == -1 : 将信号发送给所有进程。
# sig:信号的signum
# signum参考 http://blog.csdn.net/u011641885/article/details/47252003
unsigned int alarm(unsigned int seconds);
# 使用 alarm 函数可以设置一个时间值(闹钟时间),当所设置的时间到了,产生 SIGALRM 信号。
# 如果不捕捉此信号, 则默认动作是终止该进程。
# seconds : 经过指定的 seconds 秒后会产生信号 SIGALRM。
# 每个进程只能有一个闹钟时间。
# 如果在调用 alarm 时,以前已为该成绩设置过的闹钟时间,
# 而且它还没有超时,以前登记的闹钟时间则被刷新
# 如果以前登记的尚未超过的闹钟时间,
# 而这次 seconds 值是 0, 则表示取消以前的闹钟。
int pause(void);
# pause 函数使调用进程挂起直至捕捉到一个信号
# 只有执行了一个信号处理函数后,挂起才结束。
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
# 注册信号,收到执行信号后做何处理
# 参数 handler 有三种情况
# SIG_IGN : 忽略该信号
# SIG_DFL : 采用系统默认方式处理信号
# 自定义的信号处理函数指针.(执行自定义操作)
示例:
#include <signal.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void mysingal(int signum){
switch(signum){
case SIGINT:
case
break;
}
return;
}
int main(int argc, char *argv[]){
char buf[128];
signal(SIGINT,mysingal);
while(1){
printf("[email protected]> ");
fgets(buf,sizeof(buf),stdin);
if(buf[0] == ‘\r‘)
continue;
system(buf);
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。