【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 安装信号与捕捉信号 分类: Linux --- 应用程序设计 2014-11-08 13:00 49人阅读 评论(0) 收藏
2014-11-08 13:00
1041 查看
【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 安装信号与捕捉信号
(2)捕捉信号。通知内核在某种信号发生时调用一个用户函数。在用户函数中,可执行用户希望对这种事件进行的处理,这需要安装此信号。例如捕捉到SIGCHLD信号,则表示子进程已经终止,所以此信号的捕捉函数可以调用waitpid()以取得该子进程的进程PID以及它的终止状态和资源。
(3)执行系统默认操作。Linux系统对任何一个信号都规定了一个默认的操作。
示例代码:
第一个终端执行:
struct_sigaction结构
示例代码:
终端1:
终端1:
终端1:
is blocked\n");kill(getpid(),SIGUSR2);kill(getpid(),SIGUSR1);kill(getpid(),SIGALRM);sigprocmask(SIG_SETMASK,&oldmask,NULL);}
用signal设置信号处理方式,发送一次SIGUSR1,SIGUSR2,却执行了两次信号处理函数。(书上是这样说的,但是我在Ubuntu12.04中运行时,却没有出现这种漏洞的情况。)
运行结果(书上说的结果,与我运行时的结果不一致):
用sigaction设置信号处理方式只会执行一次。
运行结果:
2. signal一般不建议使用,建议使用sigaction代替。
信号处理办法
(1)忽略此信号。大多数信号都可使用这种方式进行处理,但有两种信号不能被忽略,SIGKILL和SIGSTOP。这两种信号不能被忽略的原因是:它们向超级用户提供一种使进程终止或停止的可靠方法。(2)捕捉信号。通知内核在某种信号发生时调用一个用户函数。在用户函数中,可执行用户希望对这种事件进行的处理,这需要安装此信号。例如捕捉到SIGCHLD信号,则表示子进程已经终止,所以此信号的捕捉函数可以调用waitpid()以取得该子进程的进程PID以及它的终止状态和资源。
(3)执行系统默认操作。Linux系统对任何一个信号都规定了一个默认的操作。
signal安装信号
示例代码:
#include <stdio.h> #include <unistd.h> #include <signal.h> void sig_usr(int sig); int main(int argc,char *argv[]) { int i = 0; if(signal(SIGUSR1,sig_usr) == SIG_ERR) printf("Cannot catch SIGUSR1\n"); if (signal(SIGUSR2,sig_usr) == SIG_ERR) printf("Cannot catch SIGUSR2\n"); while(1) { printf("%2d\n", i); pause(); /* pause until signal handler has processed signal */ i++; } return 0; } void sig_usr(int sig) { if (sig == SIGUSR1) printf("Received SIGUSR1\n"); else if (sig == SIGUSR2) printf("Received SIGUSR2\n"); else printf("Undeclared signal %d\n", sig); }运行结果:
第一个终端执行:
$ ./a.out & [1] 3017第二个终端执行:
$ kill -SIGUSR1 3017 $ kill -SIGUSR2 3017 $ kill -SIGABRT 3017第一个终端结果:
$ 0 Received SIGUSR1 1 Received SIGUSR2 2 [1]+ 已放弃 (核心已转储) ./a.out
sigaction安装信号
struct_sigaction结构
示例代码:
#include<stdio.h> #include<stdlib.h> #include<signal.h> void myHandler(int sig); int main(int argc,char *argv[]) { struct sigaction act, oact; act.sa_handler = myHandler; sigemptyset(&act.sa_mask); /*initial. to empty mask*/ act.sa_flags = 0; sigaction(SIGUSR1, &act, &oact); while (1) { printf("Hello world.\n"); pause(); } } void myHandler(int sig) { printf("I got signal: %d.\n", sig); } // to end program, <Ctrl + \> to generate SIGQUIT运行结果:
终端1:
$ ./a.out & [1] 3122 $ Hello world.终端2:
$ kill -SIGUSR1 3122终端1:
I got signal: 10. Hello world.
测试sa_sigaction
示例代码:#include<stdio.h> #include<stdlib.h> #include<signal.h> #include<unistd.h> void func(int signo, siginfo_t *info, void *p) { printf("signo=%d\n",signo); printf("sender pid=%d\n",info->si_pid); } int main(int argc,char *argv[]) { struct sigaction act, oact; sigemptyset(&act.sa_mask); /*initial. to empty mask*/ act.sa_flags = SA_SIGINFO; act.sa_sigaction=func; sigaction(SIGUSR1, &act, &oact); while (1) { printf("pid is %d Hello world.\n",getpid()); pause(); } }运行结果:
终端1:
$ ./a.out & [2] 3159 $ pid is 3159 Hello world.终端2:
$ kill -SIGUSR1 3159
终端1:
signo=10 sender pid=3029 pid is 3159 Hello world.
sa_flags说明
教材248页。signal的系统漏洞
示例代码:#include <stdlib.h> #include <signal.h> #include <stdio.h> static void sig_usr1(signo) { printf("SIGUSR1 function\n"); } static void sig_usr2(signo) { printf("SIGUSR2 function\n"); } static void sig_alarm(signo) { printf("SIGALRM function\n"); } int main(void) { sigset_t newmask,oldmask; /*-----signal ------------------*/ if(signal(SIGUSR1,sig_usr1) <0|signal(SIGUSR2,sig_usr2) <0 |signal(SIGALRM,sig_alarm) <0) perror("signal\n"); sigemptyset(&newmask); sigaddset(&newmask,SIGUSR1); sigaddset(&newmask,SIGUSR2); sigaddset(&newmask,SIGALRM ); /*---------signal end--------------*/ /*-----sigaction------------------*/ /*struct sigaction act1,act2,act3; act1.sa_handler=sig_usr1; sigemptyset(&act1.sa_mask);<pre name="code" class="cpp"><span style="white-space:pre"> </span>act1.sa_flags=0;//没有这句,执行后会出现段错误act2.sa_handler=sig_usr2;sigemptyset(&act2.sa_mask);
<span style="white-space:pre"> </span>act2.sa_flags=0;act3.sa_handler=sig_alarm;
sigemptyset(&act3.sa_mask);
<span style="white-space:pre"> </span>act3.sa_flags=0;;sigaction(SIGUSR1,&act1,NULL);sigaction(SIGUSR2,&act2,NULL);sigaction(SIGALRM,&act3,NULL);*//*-----sigaction--end----------------*/sigprocmask(SIG_BLOCK,&newmask,&oldmask);printf("SIGUSR
is blocked\n");kill(getpid(),SIGUSR2);kill(getpid(),SIGUSR1);kill(getpid(),SIGALRM);sigprocmask(SIG_SETMASK,&oldmask,NULL);}
用signal设置信号处理方式,发送一次SIGUSR1,SIGUSR2,却执行了两次信号处理函数。(书上是这样说的,但是我在Ubuntu12.04中运行时,却没有出现这种漏洞的情况。)
运行结果(书上说的结果,与我运行时的结果不一致):
$ ./a.out SIGUSR is blocked SIGALRM function SIGUSR2 function SIGUSR1 function<pre name="code" class="cpp">SIGALRM function SIGUSR2 function <pre name="code" class="cpp" style="font-size:18px;">SIGUSR1 function<pre name="code" class="cpp" style="font-size:18px;">SIGUSR1 function
用sigaction设置信号处理方式只会执行一次。
运行结果:
$ ./a.out SIGUSR is blocked SIGALRM function SIGUSR2 function SIGUSR1 function
注意:
1. 在某些版本的UNIX系统中,在执行完一次信号处理后有可能需要再次执行此信号的安装,因此,建议在handler函数中再次安装handler信号处理函数。当然,在目前版本的Linux系统中可以不这样做。2. signal一般不建议使用,建议使用sigaction代替。
原文链接:http://blog.csdn.net/geng823/article/details/40919567
相关文章推荐
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - Linux常见信号及处理 分类: Linux --- 应用程序设计 2014-11-08 11:54 68人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号集与屏蔽信号 分类: Linux --- 应用程序设计 2014-11-08 13:19 53人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号应用实例 分类: Linux --- 应用程序设计 2014-11-09 11:33 66人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 等待信号 分类: Linux --- 应用程序设计 2014-11-09 11:25 50人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信之消息队列 分类: Linux --- 应用程序设计 2014-11-11 13:16 71人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号量通信机制 分类: Linux --- 应用程序设计 2014-11-13 11:08 70人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础 分类: Linux --- 应用程序设计 2014-11-11 13:08 51人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 管道 分类: Linux --- 应用程序设计 2014-11-05 11:18 75人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - Linux多线程编程 - 多线程异步管理 - 信号 分类: Linux --- 应用程序设计 2014-11-30 20:33 65人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 安装信号与捕捉信号
- 【原创】《Linux高级程序设计》杨宗德著 - Linux Socket网络编程基础 - BSD Socket网络通信编程 分类: Linux --- 应用程序设计 2014-12-05 16:53 63人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 域名与IP信息解析 分类: Linux --- 应用程序设计 2014-12-18 09:56 59人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - UDP网络编程应用 分类: Linux --- 应用程序设计 2014-12-11 14:41 73人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - TCP高级应用 - socket文件描述符属性控制 分类: Linux --- 应用程序设计 2014-12-06 10:26 61人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - Linux Socket网络编程基础 - 网络通信基础 分类: Linux --- 应用程序设计 2014-12-03 22:46 71人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - TCP高级应用 - 多路复用 分类: Linux --- 应用程序设计 2014-12-05 17:57 77人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - Linux多线程编程 - 线程退出与等待 分类: Linux --- 应用程序设计 2014-11-19 18:04 64人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - Linux多线程编程 - 线程概念及创建线程 分类: Linux --- 应用程序设计 2014-11-19 17:31 82人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - Linux多线程编程 - 线程属性控制 分类: Linux --- 应用程序设计 2014-11-30 20:54 68人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - Linux多线程编程 - 线程同步机制 分类: Linux --- 应用程序设计 2014-11-21 10:44 63人阅读 评论(0) 收藏