[Linux]关于SIGCHLD

之前我们就学过,关于wait和waitpid来处理僵尸进程,父进程等待子进程结束后自己才退出,这样的方法有俩种方式,一种是父进程死死的等子进程退出,也就是使用阻塞的方式等待子进程退出,另一种方式是通过非阻塞的方式,即轮询的方式,这样父进程就可以不用浪费时间一直在那里等子进程退出,而是可以自己干自己的事,过段时间访问一次看子进程退出没,没退出的话干自己的,退出的话则回收子进程,并且自己也随即退出。那么我们是如何知道子进程是否退出呢。其实在这里,子进程终止后会给父进程发送一个SIGCHLD信号,很多同学会想,也没有见过这个信号呀,是因为这个信号的处理方式操作系统默认为忽略的方式处理的,如果你想要知道那个信号,那就用我们学过的让它的处理方式为用户自定义的处理函数即可啦。下面编写一个代码来验证一下子进程终止确实是会给父进程发送SIGCHLD信号的。

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
void myhandler(int sig)
{printf("my sig is %d\n",sig);
}
int main()
{pid_t id = fork();signal(SIGCHLD,myhandler);if(id == 0)//child{printf("i am child!pid:%d\n",getpid());sleep(5);exit(1);}else //father{while(id = waitpid(id,NULL,0) > 0){printf("wait child success:%d       pid:%d\n",id,getpid());}printf("child is quit!%d\n",getpid());}return 0;
}

运行结果:

这里写图片描述

等待子进程5秒之后:(发送了一个信号17)

这里写图片描述

我们可以看一下这个17号信号是什么:(kill -l命令)

这里写图片描述

对,就是那个SIGCHLD信号。

我们之前用sigaction来捕捉信号,当然我们也可以使用sigaction来捕捉SIGCHLD信号,在这里对于这个例子来说也叫做父进程等待子进程的异步版本,具体实现如下:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>void myhandler(int sig)
{printf("my sig is %d\n",sig);
}int main()
{signal(SIGCHLD,myhandler);pid_t cid;if((cid = fork())== 0)//child{printf("i am child!pid:%d\n",getpid());sleep(5);exit(1);}else{struct sigaction act;   act.sa_handler = myhandler;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGCHLD,&act,NULL);while(1){printf("i am parent,my pid is %d\n",getpid());sleep(1);}}
//  else //father
//  {
//      while(id = waitpid(id,NULL,0) > 0)
//      {
//          printf("wait child success:%d       pid:%d\n",id,getpid());
//      }
//      printf("child is quit!%d\n",getpid());
//  }return 0;
}

运行结果:

这里写图片描述

当子进程运行5秒后,sigaction函数捕捉到SIGCHLD信号,也即子进程退出的信号,然后父进程运行。

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

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

相关文章

C语言思维导图

本人能力有限&#xff0c;知识点难免概括不全&#xff0c;如有错误欢迎指正

pthread和互斥量条件变量函数意义速查表

数据类型 pthread_t 线程 互斥量和条件变量

[Linux]共享内存

共享内存是UNIX提供的进程间通信手段中速度最快的一种&#xff0c;也是最快的IPC形式。为什么是最快的呢&#xff0c;因为数据不需要在客户进程和服务器进程之间复制&#xff0c;所以是最快的一种IPC。这是虚存中由多个进程共享的一个公共内存块。 两个不同进程A、B共享内存的…

[Linux]gdb调试多进程多线程例程

gdb相信学linux的同学已经比较熟悉了吧&#xff0c;它是linux下代码调试工具。我们在写c语言&#xff0c;c的代码时经常会用到&#xff0c;它有一些常用的调试命令: run&#xff08;r&#xff09;&#xff1a;运行程序&#xff0c;如果有断点在下一个断点处停止 start&#xf…

[Linux]守护进程(精灵进程)

一、守护进程是什么 守护进程是生存期很长的一种进程&#xff0c;可以说它是7*24小时工作的。&#xff08;什么是7*24&#xff0c;一周7天&#xff0c;每天24小时&#xff0c;这不就是一年365天一直在工作嘛&#xff0c;还搞的这么诙谐&#xff0c;哈哈&#xff09;。它们常常…

浅谈shell中的clear命令实现

NAME(名称) clear - 清除终端屏幕 SYNOPSIS(总览) clear DESCRIPTION(描述) clear可以在允许的情况下清屏. 它会在环境变量中查找终端的类型, 然后到terminfo数据库中找出清屏的方法. 《man手册》 #include <stdio.h>int clear_main(int argc, char **argv) {/* Th…

[Linux]ARP协议

概念&#xff1a; 1. ARP协议(地址解析协议):由IP地址转换为MAC地址的协议。IP地址&#xff1a;网络号主机号。MAC地址&#xff1a;数据链路层的物理地址&#xff08;硬件地址&#xff09;。IP协议使用了ARP协议&#xff0c;因此被划归为网络层&#xff0c;但其用途是从网络层…

Makefile使用及多文件gdb 调试

文件内容 [koulocalhost makefile]$ cat 1.c #include "3.h" int main() {key_t key ftok(".",1);printf("%d\n",add(1,2));return 0; }[koulocalhost makefile]$ cat 2.c #include "3.h" int add(int a, int b) {return a b; } [k…

[Linux]CRC校验

CRC(Cyclic Redundancy Check),循环冗余校验码&#xff0c;是数据通信领域中最常用的一种差错校验码&#xff0c;其特征是信息字段和校验字段的长度可以任意选定。 CRC校验步骤&#xff1a; CRC分为两部分&#xff0c;前部分为信息码&#xff0c;后部分为校验码&#xff1b;设…

python字符串系列

1.find方法用于在长串中查找子串&#xff0c;返回子串中最左位置的下标&#xff0c;如果没找到&#xff0c;则返回-1 2.join方法用于在队列中添加元素 3.lower返回字符串的小写字母版 4.replace返回字符串中所有匹配项均被替换之后得到字符串 5.split将字符串分割成序列 6.stri…

linux网络编程Internet Socket地址,套接字,和函数

文章内容节选《linux/UNIX 系统网络编程》 Internet domain socket地址有两种&#xff1a;IPv4 IPv6 IPv4被存储在结构体中&#xff0c; 该结构体在 netinet/in.h 中进行定义 cd usr/include/netinet/in.h struct in_addr {in_addr_t s_addr; //32位IPv4地址 }struct so…

浅谈socket网络编程函数参数(一)

socket函数解析 概念: 每个进程的进程空间里都有一个socket描述符表。套接字描述符表属于一个进程&#xff0c;而socket地址结构位于操作系统的内核缓冲。 函数原型 #include <sys/socket.h>int socket(int domain, int type, int protocol);函数参数 family参数 默…

为什么计算机起始时间是1970年1月1日

1969年8月&#xff0c;贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会&#xff0c;开始着手创造一个全新的革命性的操作系统&#xff0c;他使用B编译语言在老旧的PDP-7机器上开发出了Unix的一个版本。随后&#xff0c;汤普逊和同事丹尼斯里奇改进了B语言&#xff0c;开发…

TCP三次挥手四次握手(面试总结)

1、 为什么建立连接协议是三次握手&#xff0c;而关闭连接却是四次握手呢&#xff1f; 全双工通信。 这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后&#xff0c;它可以把ACK和SYN&#xff08;ACK起应答作用&#xff0c;而SYN起同步作用&#xff09;放在一个…

csdn怎么快速转载别人的文章

如何转载 用谷歌浏览器加载文章地址&#xff0c;打开文章F12打开Developer Tools&#xff0c;并打开Elements页面 将文章开头部分的文字作为关键字在Elements界面搜索 以此文为例&#xff1a;http://blog.csdn.net/aggressive_snail/article/details/54375876 搜索找了好久关…

解释性语言和汇编性语言对比

解释性语言和编译型语言的区别和不同解释性语言编译型语言概念计算机不能直接的理解高级语言&#xff0c;只能直接理解机器语言&#xff0c;所以必须要把高级语言翻译成机器语言&#xff0c;计算机才能执行高级语言的编写的程序。翻译的方式有两种&#xff0c;一个是编译&#…

C++ 菱形继承 的 对象模型01

先看 普通菱形继承 #include <iostream> #include <string> using namespace std; class Animal {int a_age; }; class Sheep : public Animal {}; class Tuo : public Animal {}; class SheepTuo : public Sheep, public Tuo {}; void test1() {cout << …