Linux信号(一)——子进程的异步等待方式
2017-06-16 18:50
337 查看
1.信号
信号(是一种软件中断)是由用户、系统或者进程发送给目标进程的信息,以通知目标进程某个状态的改变或系统异常。2.信号的产生
(1)前台进程,用户可以通过输入特殊终端字符来给它发送信号。比如Ctrl+C通常给进程发送一个中断信号——2号信号(SIGINT),只能终止前台进程(后台进程一般在运行后面加&,就可以使得进程在后台运行)。(2)系统异常。比如浮点异常——8号信号(SIGFPE)。
(3)系统状态变化。比如alarm函数定时器到期引起14号信号——SIGALRM信号。
(4)运行kill命令调用kill函数。产生9号信号——SIGKILL(该信号不能被定义或捕捉,该信号用来杀死进程)。
3.信号的分类
列表中,编号为1~31号信号为普通信号,也称为不可靠信号;编号34~64为后来扩充的,被称作可靠信号(实时信号);不可靠信号和可靠信号二者的区别是前者不支持排队,可能会造成信号丢失,
后者不会。
4.Linux信号处理方式
(1)忽略此信号。大多数信号都可以使用这种方式进行处理,除了9)SIGKILL和19)SIGSTOP。这两种信号不能被忽略的原因:它们是用来终止进程的一种可靠的方法。如果忽略某些由硬件异常所产生的信号(例如非法存储访问或除以0),则进程的行为是未定义的。(2)执行默认动作(大部分的默认动作就是终止该进程(Term)),还有比如:忽略信号(Ign)、结束进程并生成核心转储文件(Core)、暂停进程(Stop)、以及继续进程(Cont)。
(3)捕捉信号。提供一个自定义的动作。
5.信号相关函数
(1)signal函数#include<signal.h> void(*signal (int signo ,void (*func)(int))) (int); //返回则为以前的信号处理配置,若出错则为SIG_ERRsigno参数是上图的信号名。
func的值为:
如果指定为常数SIG_IGN,代表内核忽略此信号(SIGKILL和SIGSTOP不能忽略) ;
如果指定为常数SIG_DFL,代表接到此信号之后执行系统默认动作
如果指定为函数地址时,我们称捕捉此信号。
(2)kill和raise函数
#include <sys/types.h> #include <signal.h> int kill (pid_t pid, int signo); int raise(int signo); //两个函数返回:成功则为0,若出错则为-1
kill命令调用kill函数实现,kill函数给一个指定的进程发送指定的信号
raise函数只允许进程向自身发送信号
6.验证子进程退出会给父进程发送信号
测试代码:#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <signal.h> #include <error.h> void catchsignal(int sig) { printf("I am a father my pid is:%d , receive signal is %d\n",getpid(),sig); } int main() { signal(SIGCHLD,catchsignal); pid_t id=fork(); if(id==0){ //child int count=0; while(count<4){ printf("I am a child,my pid is: %d ,my father's pid is: %d \n",getpid(),getppid()); sleep(1); count++; } exit(0); } else if(id>0){ 4000 //father waitpid(id,NULL,0); } else{ perror("fork error\n"); } return 0; }
运行结果:
很明显子进程退出时父进程收到了17号信号——17)SIGCHLD。
7.编写父进程等待子进程的异步版本
异步:父子进程互不干扰(非阻塞式等待),继续执行各自任务。
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <signal.h> #include <error.h> void catchsignal(int sig) { printf("I am a father my pid is:%d , receive signal is %d\n",getpid(),sig); } int main() { signal(SIGCHLD,catchsignal); pid_t id=fork(); if(id==0){ //child int count=0; while(count<4){ printf("I am a child,my pid is: %d ,my father's pid is: %d \n",getpid(),getppid()); sleep(1); count++; } exit(0); } else if(id>0){ //father while(1){ sleep(2); printf("I am a father,running\n"); } } else{ perror("fork error\n"); } return 0; }
运行结果:
相关文章推荐
- 关于子进程异步等待方式(SIGCHLD信号)
- 【Linux】子进程的异步等待方式
- 【Linux】子进程的异步等待方式
- 【Linux】子进程的异步等待方式
- Linux日常——信号(4)子进程的异步等待方式
- 子进程的异步等待方式——SIGCHLD信号
- Linux下父进程异步等待子进程
- Linux子进程的异步等待方式(SIGCHLD信号)
- 进程等待及子进程异步等待方式
- Linux父进程对于子进程的异步等待
- 验证子进程退出时会给父进程发送信号的机制 、 编写父进程等待子进程的异步版本
- linux 异步信号的同步处理方式
- Linux 进程间通信 --- 信号通信 --- signal --- signal(SIGINT, my_func); --- 按键驱动异步通知
- linux驱动的异步通知 驱动程序向应用程序发送信号
- 子进程的异步等待方式
- linux驱动的异步通知(kill_fasync,fasync)---- 驱动程序向应用程序发送信号
- 进程间通信--信号(进程间通信唯一的异步方式
- c# 等待异步委托结果的三种方式
- 子进程的异步等待方式
- Socket层实现系列 — 信号驱动的异步等待