signal函数-进程对信号的响应

来源:互联网 发布:淘宝app怎么收藏店铺 编辑:程序博客网 时间:2024/05/21 06:58

1.signal函数

#include <signal.h>

void (*signal(int signo, void (*func)(int)))(int);

返回:若成功则返回先前的信号处理函数指针,出错则返回SIG_ERR;

功能:向内核登记信号处理函数;

参数:signo:要登记的信号值

     func:a.信号处理函数指针;b.SIG_IGN,忽略信号;c.SIG_DFL,采用系统默认的方式处理信号,执行默认操作


2.进程对信号的三种响应

下面以SIGINT信号为例,对这三种响应方式进行说明。

(1)忽略信号,signal(SIGINT,SIG_IGN);

SIG_IGN代表忽略SIGINT信号,SIGINT信号代表由InterruptKey产生,通常是Ctrl+C或者是DELETE。发送给所有ForeGround Group的进程。

下面我们写个死循环:

#include <stdio.h>#include <signal.h>int main(void){     signal(SIGINT, SIG_IGN);     for(;;);     return 0;}
这时我们保存执行,按下Ctrl+C程序没有反应,这就对了。

如果我们想结束该程序可以按下Ctrl+\来结束

其实当我们按下Ctrl+\组合键时,是产生了SIGQUIT信号。


(2)执行默认操作,signal(SIGINT, SIG_DFL)

SIG_DFL代表执行系统默认操作,其实对于大多数信号的系统默认动作是终止改进程,与不写此处理函数的效果是一样的。

#include <stdio.h>#include <signal.h>int main(void){     signal(SIGINT, SIG_DFL);     for(;;);     return 0;}
这时就可以按下Ctrl+C来终止该进程了。把signal(SIGINT, SIG_DFL)这句去掉,效果是一样的。


(3)捕获信号,signal(SIGINT, sig_handler);

#include <stdio.h>#include <signal.h>void sig_handler(int signo){     printf("catch the signal:%d", signo);}int main(void){     // 登记一下SIGINT信号     if(signal(SIGINT, sig_handler) == ERR)     printf("signal error");     for(;;);     return 0;}
这种情况下,当按下Ctrl+C时,会执行我们定义的信号处理函数。

想要退出,可以按下Ctrl+\


3.对信号处理的几点说明

(1) SIGKILL和SIGSTOP这两个信号永远不能忽略;

(2) SIGKILL和SIGSTOP不能被捕获(即使已经登记了,也不能被捕获);

(3) 进程启动时SIGUSR1和SIGUSR2两个信号被忽略;


4.几个常见的信号

(1)SIGINT,编号为2,相当于执行Ctrl+C;

(2)SIGTSTP,编号为20,相当于Ctrl+Z,暂停一个进程;

(3)SIGCONT,编号为18,继续执行被暂停的信号,格式为:kill -SIGCONT/18 进程ID

(4)SIGCHLD,编号为17,子进程结束产生该信号;(信号的异步处理表现在:当SIGCHLD产生时,父进程对其捕获处理,其他时间父进程该干嘛干嘛)

下面举例来说明SIGCHLD信号的用法。

#include <signal.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>void sig_handler(int signo){printf("child process deaded, signo: %d\n", signo);wait(0);// 当捕获到SIGCHLD信号,父进程调用wait回收,避免子进程成为僵尸进程}void out(int n){int i;for(i = 0; i < n; ++i){printf("%d out %d\n", getpid(), i);sleep(2);}}int main(void){// 登记一下SIGCHLD信号if(signal(SIGCHLD, sig_handler) == SIG_ERR){perror("signal sigchld error");}pid_t pid = fork();if(pid < 0){perror("fork error");exit(1);}else if(pid > 0){// parent processout(100);}else{// child processout(10);}return 0;}

2 0
原创粉丝点击