信号的捕捉以及SIGCHLD信号

一. 信号的捕捉定义

    用户提供一个处理函数, 要求内核在处理信号时必须切换到用户态,执行这个函数, 这种方式就叫做信号的捕捉

二. 图解信号的捕捉过程

这里写图片描述
    1. 由上图可以看出,当处理信号的执行动作时用户自定义的时候,此时就需返回该函数去调用该函数, 这就叫做信号的捕捉. 以前我们总是说进程收到信号时会在合适的时候取处理该信号, 现在可以看出,这个合适的时候就是当进程处理完中断时, 需需要从内核态返回到用户态的时候就需要处理能够递达的信号.举个例子, 用户注册了一个信号, 当系统进程正在执行主控制流的时候, 发现有异常中断产生, 此时系统从用户态转到内核态, 处理完异常中断时, 需要返回到main函数时,检测是否有可以递达的信号,发现有一个可以递达的信号, 而该信号的处理动作是用户自定义类型(signalhandle), 于是系统就从内核态切换到用户态去执行该信号的执行动作(signalhandle), 当处理完这个函数的时候, 系统不能直接返回到主控制流, 而是先通过 sigreturn 切换到内核状态, 此时再继续检测是否有可以递达的信号, 发现没有, 于是系统切换到用户态, 返回到刚刚被切换的主控制流处继续执行下面的代码.(注意main函数和signalhandle 之间使用不同的堆栈结构,它们之间不存在调用和被调用的关系, 是两个独立的控制流)

三. 相关接口函数

    1. 捕捉信号的相关接口
            这里写图片描述
;            这里写图片描述
    该函数是用来读取和修改相关对信号操作的处理动作. 其中signum 是信号的编号, act 和 oact 是一个指向结构体 sigaction 的指针, act 用来存放需要修改的函数处理动作, oldact 用来保存原有的处理信号的动作, 是一个输出型参数, 可以传出原有的信号处理的动作. signal 函数中 signum 指的是信号的编号, handle 赋值为 SIGIGN 时表示忽略该信号, 当赋值为 SIG_DFL 时表示执行默认动作. 也可以赋值为函数指针, 表示执行用户自定义函数, 即捕捉信号.该函数同样不是被 main函数调用, 而是被系统调用.
    2. 挂起进程的相关接口
                                        这里写图片描述
     该函数用于将调用进程挂起直到有信号递达. 如果信号的执行动作是终止信号, 则进程终止,pause 不返回 如果该信号的执行动作是忽略, 则进程继续处于挂起, pause 不返回.如果信号的执行动作是捕捉, 则pause 返回 -1. 即pause 只有出错时才有返回值

四. SIGCHLD信号

    该信号用于子进程退出时操作系统向父进程发送一个SIGCHLD信号,通知父进程回收子进程, 试想, 当我们将SIGCHLD信号捕捉, 然后将该信号的处理动作设为 SIG_IGN, 忽略该信号, 此时父进程将永远不可能回收子进程, 即子进程也不会变成僵尸进程

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>void handler(int sig)
{pid_t pid;while( (pid = waitpid(-1, NULL, WNOHANG)) > 0 ){printf("wait child is sucessful\n");}printf("child is quit\n");
}
int main()
{pid_t pid;signal(SIGCHLD, handler);pid = fork();if(pid == 0){printf("I am child\n");exit(1);}else if(pid > 0){while(1){printf("father is doing somthing\n");sleep(1);}}return 0;
}

                  这里写图片描述
     此时可以看见给父进程发送一个SIGCHLD 信号,之后, 子进程也会被回收

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384068.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

链队 尹成

http://blog.csdn.net/itcastcpp/article/details/39271691 今天&#xff0c;我们一起用C写一个链对&#xff0c;具体如下所示。 LinkQueue.h具体内容如下&#xff1a; [cpp] view plaincopy #include "QueueNode.h" template<typename Type> class LinkQueu…

强连通分量入门——Trajan算法

今天学习了强连通分量。 【参考博客】 如果觉得我讲的有些地方难以理解或者存在问题&#xff08;欢迎留言&#xff09;&#xff0c;可以看一下我借鉴的一些大佬的博客&#xff1a; 传送门1 传送门2 【知识储备】 首先我们需要对几个定义有一些概念&#xff1a; 强连通&#xff…

最小栈的实现

所谓最小栈, 就是当前栈顶元素最小, 我们可以这样做, 每次在入栈之前, 将待入栈元素与栈顶元素相比, 每次现将待入栈的元素先入栈, 再将带入栈的元素和较小的元素入栈, 这样就可以保证每次栈顶元素是最小元素. 在出栈的时候规定每次出栈两个元素,这样就可以保证在出栈之后栈顶元…

用C++实现单链表的创建、逆置和输出 的两种方法

http://blog.csdn.net/lfeng_coding/article/details/47300563 题目描述&#xff1a;在已知单链表头节点的情况下&#xff0c;设计算法逆置单链表并输出 方法一&#xff1a;采用首先将头节点指向空&#xff0c;让其变为尾节点&#xff0c;然后利用中间节点 p、q 将其后的节点一…

两个栈实现一个队列

利用两个栈实现一个队列思路是这样的. 首先这个队列包含两个栈, 然后一个栈用来入队列, 一个栈用来出队列 typedef struct QueBy2Stack {SeqStack input;SeqStack output; }QueBy2Stack; 1. 初始化 void QueBy2StackInit(QueBy2Stack* stack) {if(stack NULL){return;//非法…

HDU 5934:Boom——强连通分量+缩点

【题目描述】 There are N bombs needing exploding.Each bomb has three attributes: exploding radius ri, position (xi,yi) and lighting-cost ci which means you need to pay ci cost making it explode.If a un-lighting bomb is in or on the border the exploding ar…

Linux--线程死锁

http://blog.csdn.net/gebushuaidanhenhuai/article/details/73799824 线程为什会死锁&#xff1f;&#xff1f;“锁”又是什么东西&#xff1f;我们这篇博客主要讲一下为什么要给线程加锁&#xff0c;为什么会出现线程死锁&#xff0c;线程死锁怎么解决。 互斥锁 在我的上篇博…

两个队列实现一个栈

用两个队列实现一个栈的原理是这样的. 规定两个队列, 必须有一个队列是非空, 一个队列是空.每次入栈时必须往非空队列中入, 而每次出栈时, 必须将非空队列里的元素装到空队列中, 直到非空队列中只有一个元素时, 此时就将剩下的这个元素出栈即可. 而取栈顶元素时, 和出栈一样, 先…

POJ-1144 Network——Trajan+割点

【题目描述】 A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N . No two places have the same number. The lines are bidirectional and always connect together tw…

Linux--生产者与消费者

http://blog.csdn.net/gebushuaidanhenhuai/article/details/74011636 基本概念 提到生产者和消费者&#xff0c;我们最有可能想到的是商店卖东西&#xff0c;顾客在货架上(缓冲区&#xff09;买东西。 生产者消费者问题&#xff0c;其实是一个多线程同步问题的经典案例。该问…

进程的挂起以及可重入函数

相关接口     pause 函数用于将进程挂起. 如果信号的处理动作是终止进程, 则进程终止, pause 函数没有返回值; 如果信号的处理动作是忽略, 则进程被挂起, pause函数不返回, 如果信号的处理动作是捕捉, 则调用信号处理动作之后pause 返回 -1.来看一段代码 #include<s…

POJ1236Network of Schools——强连通分量缩点建图

【题目描述】 A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the “receiving schools”). Note that if B is in the distri…

C——通过调用函数分配内存

http://blog.csdn.net/u012627502/article/details/3579724 1&#xff09;以返回值方式返回&#xff1a;把动态分配的存储位置地址&#xff0c;赋值给指针类型返回值&#xff08;不同于被调用函数的自动变量地址&#xff09; 2&#xff09;以形参形式返回&#xff1a;二级指针类…

gdb调试多进程程序

1.gdb下调试多进程程序只需要以下几条命令即可              除此之外还可以查看正在调试的进程 info inferiors, 同时也可以将当前正在调试的进程切换到另外一个进程中让其取运行     2.代码调试演示 #include<stdio.h> #include<stdlib.h> #…

BZOJ1123-BLO——强连通分量求割点+计数

【题目描述】 Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。Input 输入n<100000 m<500000及m条边Output 输出n个数&#xff0c;代表如果把第i个点去掉&#xff0c;将有多少对点不能互通。Sample Input 5…

关于memcpy和memmove两函数的区别

http://blog.csdn.net/caowei840701/article/details/8491836 [cpp] view plaincopy <p> 关于memcpy和memmove两个c标准库函数&#xff0c;其功能都是将一块内存区域中的指定大小内容复制到目标内存中&#xff0c;在翻阅c标准库实现的源代码我们发现他们是有区别的。&…

判断字符串出栈合法性

先来看说一下思路 接下来就是写代码了 int StackOrder(SeqStack* stack, char* input, char* output, int size_input, int size_output) {if(stack NULL || input NULL || output NULL){return 0;}int i_input 0;int j_output 0;SeqStackType value;for(; j_output <…

CodeForces - 1200C——小模拟

【题目描述】 Amugae is in a very large round corridor. The corridor consists of two areas. The inner area is equally divided by n sectors, and the outer area is equally divided by m sectors. A wall exists between each pair of sectors of same area (inner o…

1 单例模式

达内 闵大神 //饿汉单例模式 #include <iostream> using namespace std;class Singleton { public:static Singleton& getInstance(){return s_instance;} private:Singleton(){}Singleton(const Singleton& that){}static Singleton s_instance;//静态成员变量 …

共享栈

1.定义 所谓共享栈就是利用一个数组实现两个栈. 先来看一下共享栈的数据结构 typedef struct SharedStack {int top1;int top2;SeqStackType* data; }SharedStack; 2. 初始化 void SharedStackInit(SharedStack* stack) {if(stack NULL){return;//非法输入}stack -> top…