[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.pswp.cn/news/382697.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/382697.shtml
英文地址,請注明出處:http://en.pswp.cn/news/382697.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言思維導圖

本人能力有限&#xff0c;知識點難免概括不全&#xff0c;如有錯誤歡迎指正

轉載一篇關于curl的文章

轉載一篇關于curl的文章 http://www.360doc.com/content/16/0107/15/18578054_526158476.shtml

[Linux]vi/vim下添加多行注釋和取消注釋

添加注釋&#xff08;Centos&#xff09;&#xff1a; 在命令行模式下按ctrlV進入 visual block模式&#xff08;可視化模式&#xff09; 選中你需要注釋的行&#xff0c;再按大寫的I&#xff0c;輸入//&#xff0c;最后按倆下esc即可。 如果想讓前進tab個位&#xff0c;則可在…

pthread和互斥量條件變量函數意義速查表

數據類型 pthread_t 線程 互斥量和條件變量

[Linux]共享內存

共享內存是UNIX提供的進程間通信手段中速度最快的一種&#xff0c;也是最快的IPC形式。為什么是最快的呢&#xff0c;因為數據不需要在客戶進程和服務器進程之間復制&#xff0c;所以是最快的一種IPC。這是虛存中由多個進程共享的一個公共內存塊。 兩個不同進程A、B共享內存的…

僵尸進程的產生,危害和解決方案

概念 僵死狀態&#xff08;Zombies&#xff09;是一個比較特殊的狀態。 當進程退出并且父進程沒有讀取到子進程退出的返回代碼時就會產生僵尸進程。僵尸進程會以終止狀態保持在進程表中&#xff0c;并且會一直在等待父進程讀取退出狀態代碼。所以&#xff0c;只要子進程退出&…

CString string 轉換

https://www.cnblogs.com/HappyEDay/p/7016162.html

[Linux]gdb調試多進程多線程例程

gdb相信學linux的同學已經比較熟悉了吧&#xff0c;它是linux下代碼調試工具。我們在寫c語言&#xff0c;c的代碼時經常會用到&#xff0c;它有一些常用的調試命令: run&#xff08;r&#xff09;&#xff1a;運行程序&#xff0c;如果有斷點在下一個斷點處停止 start&#xf…

gdb調試常用命令速查(段錯誤調試)

編譯程序時需要加上-g&#xff0c;之后才能用gdb進行調試&#xff1a;gcc -g main.c -o main gdb中命令&#xff1a; 回車鍵&#xff1a;重復上一命令 &#xff08;gdb&#xff09;help&#xff1a;查看命令幫助&#xff0c;具體命令查詢在gdb中輸入help 命令,簡寫h &…

C語言字符串 小記

#include "stdafx.h" #include <iostream> #include <string.h> using namespace std;int _tmain(int argc, _TCHAR* argv[]) {char str1[] "12345"; // ""括起來的字符串 會在末尾增加 \0 cout << sizeof(str1) << en…

[Linux]守護進程(精靈進程)

一、守護進程是什么 守護進程是生存期很長的一種進程&#xff0c;可以說它是7*24小時工作的。&#xff08;什么是7*24&#xff0c;一周7天&#xff0c;每天24小時&#xff0c;這不就是一年365天一直在工作嘛&#xff0c;還搞的這么詼諧&#xff0c;哈哈&#xff09;。它們常常…

linux命令行界面下ctrl 常用組合鍵速查表

Ctrlz 暫停正在運行的程序 Ctrll 清屏 Ctrld 結束輸入或退出shell Ctrla 切換到命令行開始 Ctrle 切換到命令行末尾 Ctrlu 刪除光標前內容 Ctrlk 刪除光標后內容 Ctrlxu 撤銷操作

[Linux]運輸層的端口

既然提到端口&#xff0c;我們就來分析一下為什么要使用端口的緣由吧。我們首先要知道的是&#xff0c;運輸層有復用和分用的功能。應用層所有的應用進程都可以通過運輸層再傳送到IP層&#xff0c;這就是復用。運輸層從IP層收到數據后必須交付到指明的應用進程&#xff0c;這就…

淺談shell中的clear命令實現

NAME(名稱) clear - 清除終端屏幕 SYNOPSIS(總覽) clear DESCRIPTION(描述) clear可以在允許的情況下清屏. 它會在環境變量中查找終端的類型, 然后到terminfo數據庫中找出清屏的方法. 《man手冊》 #include <stdio.h>int clear_main(int argc, char **argv) {/* Th…

C++ 對引用的理解

引用可以看做是數據的一個別名&#xff0c;通過這個別名和原來的名字都能夠找到這份數據引用必須在定義的同時初始化&#xff0c;并且以后也要從一而終&#xff0c;不能再引用其它數據&#xff0c;這有點類似于常量&#xff08;const 變量&#xff09;。引用變量 里面 實際存儲…

[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…

C++ 對引用的理解2

1.指針就是數據或代碼在內存中的地址&#xff0c;指針變量指向的就是內存中的數據或代碼。這里有一個關鍵詞需要強調&#xff0c;就是內存&#xff0c;指針只能指向內存&#xff0c;不能指向寄存器或者硬盤&#xff0c;因為寄存器和硬盤沒法尋址。 2.其實 C 代碼中的大部分內容…

Ubuntu各版本主要差異

Ubuntu各版本主要差異 (重定向自Ubuntu &#xff0c; kubuntu與xubuntu的差別 ) Ubuntu官方考慮到使用者的不同需求&#xff0c;提供各種不同的發行版。這幾種發行版本的差別在于桌面環境和預設安裝的軟體不同&#xff0c;但套件庫是采用一樣的&#xff0c;所以您當然可以在安…

[Linux]CRC校驗

CRC(Cyclic Redundancy Check),循環冗余校驗碼&#xff0c;是數據通信領域中最常用的一種差錯校驗碼&#xff0c;其特征是信息字段和校驗字段的長度可以任意選定。 CRC校驗步驟&#xff1a; CRC分為兩部分&#xff0c;前部分為信息碼&#xff0c;后部分為校驗碼&#xff1b;設…