Linux编程signal函数使用
题目:
编写一段程序,使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:
Child process 1 is killed by parent!
Child process 2 is killed by parent!
父进程等待两个子进程终止后,输出以下信息后终止:
Parent process is killed!
原始程序:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>void go();
void stop1(),stop2();int p1,p2;main( )
{ while((p1=fork( ) )==-1); /*创建子进程p1*/if (p1>0){while((p2=fork( ) )==-1); /*创建子进程p2*/if(p2>0){ printf("This is parent %d.\n", getpid()); signal(SIGINT,go); /*接收到信号,转go*/pause();sleep(2); // wait for the operation of childwait(0);wait(0);printf("Parent process is killed!\n");exit(0);}else if(p2 == 0){ printf("This is child_2 %d.\n", getpid()); signal(17,stop2); /*接收到软中断信号17,转stop2*/pause();}}else if(p1 == 0){ printf("This is child_1 %d.\n", getpid()); signal(16,stop1); /*接收到软中断信号16,转stop1*/pause();}
}void go()
{kill(p1,16); /*向p1发软中断信号16*/kill(p2,17); /*向p2发软中断信号17*/
}void stop2()
{printf("Child process 2 is killed by parent!\n");exit(0);
}void stop1()
{printf("Child process 1 is killed by parent!\n");exit(0);
}
但是这段程序,并没有按照预期的结果,输出“Child process 1 is killed by parent”和"Child process 2 is killed by parent!"。
在输入Ctrl+C后,父进程和子进程同时结束了,子进程并没有处理为其设置的信号,是什么原因呢?
因为子进程从父进程中继承了Ctrl+C信号,及其默认的处理程序,在子进程中并没有屏蔽Ctrl+C信号,因此,当输入Ctrl+C信号时,子进程会在处理父进程为其指定的信号之前,调用默认的处理Ctrl+C信号的程序,直接退出。因此,解决这个问题的办法,就是在子进程中屏蔽掉系统默认的对Ctrl+C信号的处理,如下:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>#include <unistd.h>
void go();
void stop1(),stop2();
pid_t p1,p2;
void main( )
{ int status = -1;int rtv;while((p1=fork( ) )==-1); /*创建子进程p1*/if (p1>0){while((p2=fork( ) )==-1); /*创建子进程p2*/if(p2>0){ printf("Parent process %d\n", getpid());signal(SIGINT,go); /*接收到信号,转go*/pause();sleep(2);wait(NULL);wait(NULL);printf("Parent process is killed!\n");exit(0);}else{ printf("Process 2, pid %d\n", getpid());signal(SIGINT, SIG_IGN); //屏蔽默认的 SIGINT信号处理signal(SIGUSR2, stop2);if(signal(SIGUSR2,stop2) == SIG_ERR) {printf("Can't catch SIGUR2");}pause();printf("Process 2 End\n");}}else{ printf("Process 1, pid %d\n", getpid());signal(SIGINT, SIG_IGN); //屏蔽默认的 SIGINT信号处理
if(signal(SIGUSR1,stop1) == SIG_ERR) {printf("Can't catch SIGUR2");}pause();printf("Process 1 End\n");}printf("child exit status is %d\n", WEXITSTATUS(status));
}void go()
{int rtv;printf("Func go\n");rtv = kill(p1,SIGUSR1); /*向p1发软中断信号16*/if(rtv) {printf("fail to send signal 16 to p1\n");} else {printf("Succed in sending signal 16 to p1\n");}rtv = kill(p2,SIGUSR2); /*向p2发软中断信号17*/if(rtv) {printf("fail to send signal 17 to p2\n");} else {printf("Succed in sending signal 17 to p2\n");}
}
void stop2()
{printf("Child process 2 is killed by parent!\n");exit(0);
}
void stop1()
{printf("Child process 1 is killed by parent!\n");exit(0);
}
参考:UNIX环境高级编程_第二版中文
Linux编程signal函数使用相关推荐
- linux中signal函数返回值,signal函数、sigaction函数及信号集操作函数
信号是与一定的进程相联系的.也就是说一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如一个进程可以忽略某些信号而只处理其他一些信号另外一个进程还可以选择如何处理信号.总之这些总与特定的进程相联 ...
- linux中signal函数的简单用法
信号是软件中断,它提供了一种处理异步事件的方法,每个信号有个以SIG打头的名字,讲signal函数之前我们先了解下当前系统所支持的信号名称,在linux中敲下kill -l就能查看. [lingyun ...
- linux 编程--prctl()函数应用
int prctl ( int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5 ) ...
- Linux中signal函数
signal函数介绍 #include <signal.h> signal(参数1,参数2): 参数1:我们要进行处理的信号.系统的信号我们可以再终端键入kill -l查看(共64个).其 ...
- linux下signal()函数超详细介绍
1. 功能 设置某一信号的对应动作 2. 声明 #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t si ...
- linux编程 fmemopen函数打开一个内存流 使用FILE指针进行读写访问
fmemopen()函数打开一个内存流,使你可以读取或写入由buf指定的缓冲区.其返回FILE*fp就是打开的内存流,虽然仍使用FILE指针进行访问,但其实并没有底层文件(并没有磁盘上的实际文件,因为 ...
- linux编程-open函数和write函数实现copy命令
文章目录 文件描述符 文件描述符 所有的I/O操作的系统调用都以文件描述符,一个非负整数(通常是小整数),来指代打开的文件. open函数打开pathname所标识的文件,并返回文件描述文件描述符 ...
- linux signal函数用法,linux信号机制之sigaction构造体浅析,signal 函数,信号捕捉.
来自:http://hi.baidu.com/phenix_yw/blog/item/6eb4ca391d1479f23a87ce19.html 信号安装函数sigaction(int signum, ...
- 理解signal函数
关键字:Unix , Linux, signal, 函数指针,指针函数 在Unix/Linux中signal函数是比较复杂的一个,其定义原型如下: void (*signal(int signo,vo ...
最新文章
- ⑨①-成功者的路永远都是相通的
- gradle 指定springcloud 版本_Gradle初探
- FFmpeg转码指令(测试通过)
- QT的QEasingCurve类的使用
- 程序员作图工具和技巧,你 get 了么?
- 一个简单限速器的java实现[1]
- 计算机体系结构a类会议,通信、计算机等领域常见A类国际学术会议.PDF
- 学习linux—— 磁盘相关指令
- ModuleNotFoundError: No module named xxx 解决办法
- 【路径规划】基于matlab蚁群算法求解机器人栅格地图最短路径规划问题【含Matlab源码 1618期】
- 编写一个应用程序,给出汉字‘你’、‘我’、‘他’在Unicode表中的位置。
- 永恒之蓝漏洞自查-MS17010漏洞自查与修复
- cygwin下使用apt-cyg安装新软件
- 编写一个函数,简单模拟微信发红包算法。
- idea如何设置jvm大小
- innerHTML,outerHTML innerHTML
- Hexo+Buttterly+Github Pages构建个人博客
- 【0091】【创建postgres后端进程】PostgreSQL如何接收并处理客户端的socket请求(4)?
- fatal: --author ‘minfg‘ is not ‘Name <email>‘ and matches no existing author
- 简单c语言程序(switch语句)输入1-7,输出周一到周日