Linu系統編程---9(SIGCHLD 信號,信號傳參,中斷系統調用)

SIGCHLD 信號

SIGCHLD 的產生條件

  1. 子進程終止時
  2. 子進程接收到 SIGSTOP 信號停止時
  3. 子進程處在停止態,接受到 SIGCONT 后喚醒時

借助 SIGCHLD 信號回收子進程

子進程結束運行,其父進程會收到 SIGCHLD 信號。該信號的默認處理動作是忽略。可以捕捉該信號,在捕捉函 數中完成子進程狀態的回收。

linux系統根據未決信號集來處理信號,多個信號進入未決信號集只處理一次。

#include<stdio.h>                                                                    
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<signal.h>//出錯處理函數
void sys_err(char * str)
{perror(str);exit(1);
}void do_sig_child(int signo)
{int status;//傳出參數pid_t pid;//進程ID//status子進程退出狀態while((pid = waitpid(0,&status,WNOHANG))>0){if(WIFEXITED(status))printf("--------child %d exit %d\n",pid,WEXITSTATUS(status));else if(WIFSIGNALED(status))printf("child %d cancel signal %d\n",pid,WTERMSIG(status));}   
}int main(void)
{pid_t pid;int i;//阻塞SIGCHLDfor(i=0;i<10;i++){if((pid = fork()) == 0){ break;}else if(pid<0){sys_err("fork");}}if(pid == 0){int n=1;while(n--){printf("child ID %d\n",getpid());sleep(1);}return i+1;}else if(pid >0 ){//有可能再注冊信號過程中子進程死亡,所以要先對SIGCHILD信號進程阻塞//SIGCHILD阻塞struct sigaction act;act.sa_handler = do_sig_child;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGCHLD,&act,NULL);//解除對SIGCHLD的阻塞while(1){printf("Parent ID %d\n",getpid());sleep(1);}}return 0;
}          

在這里插入圖片描述

子進程結束 status 處理方式

pid_t	waitpid(pid_t		pid,int*	status,int	options) 
  1. options
    WNOHANG
    沒有子進程結束,立即返回
    WUNTRACED
    如果子進程由于被停止產生的 SIGCHLD,waitpid 則立即返回
    WCONTINUED
    如果子進程由于被 SIGCONT 喚醒而產生的 SIGCHLD,waitpid 則立即返回
  2. 獲取 status
    WIFEXITED(status)
    子進程正常 exit 終止,返回真
    WEXITSTATUS(status)返回子進程正常退出值
    WIFSIGNALED(status)
    子進程被信號終止,返回真
    WTERMSIG(status)
    返回終止子進程的信號值
    WIFSTOPPED(status) 子進程被停止,返回真
    WSTOPSIG(status)返回停止子進程的信號值 WIFCONTINUED(status)

SIGCHLD 注意

  1. 子進程繼承了父進程的信號屏蔽字和信號處理動作,但子進程沒有繼承未決信號集 spending。
  2. 注意注冊信號捕捉函數的位置。
  3. 應該在 fork 之前,阻塞 SIGCHLD 信號。注冊完捕捉函數后解除阻塞。

信號傳參

發送信號傳參

sigqueue 函數對應 kill 函數,但可在向指定進程發送信號的同時攜帶參數 int sigqueue(pid_t pid,int sig,const union sigvalvalue);成功:0;失敗:-1,設置

errno union	sigval
{ int sival_int;void*sival_ptr;//這個地址給本進程使用
};

向指定進程發送指定信號的同時,攜帶數據。但,如傳地址,需注意,不同進程之間虛擬地址空間各自獨立, 將當前進程地址傳遞給另一進程沒有實際意義。

捕捉函數傳參

int	sigaction	(int	signum,const	struct	sigaction*act,struct	sigaction*oldact);structsigaction{ void       (*sa_handler)(int); void  	 (*sa_sigaction)(int,siginfo_t*,void*); sigset_t 	sa_mask;int 	sa_flags; void 	(*sa_restorer)(void);}; 

當注冊信號捕捉函數,希望獲取更多信號相關信息,不應使用 sa_handler 而應該使用 sa_sigaction。但此時的 sa_flags 必須指定為 SA_SIGINFO。siginfo_t 是一個成員十分豐富的結構體類型,可以攜帶各種與信號相關的數據。

中斷系統調用

系統調用可分為兩類:慢速系統調用其他系統調用。

慢速系統調用:

可能會使進程永遠阻塞的一類。如果在阻塞期間收到一個信號,該系統調用就被中斷,不再 繼續執行(早期);也可以設定系統調用是否重啟。如,read、write、pause、wait…

其他系統調用:

getpid、getppid、fork…

結合 pause,
回顧慢速系統調用:
慢速系統調用被中斷的相關行為,實際上就是 pause 的行為:
如,read

  1. 想中斷 pause,信號不能被屏蔽。
  2. 信號的處理方式必須是捕捉 (默認、忽略都不可以)
  3. 中斷后返回-1,
    設置 errno 為 EINTR(表“被信號中斷”) 可修改 sa_flags 參數來設置被信號中斷后系統調用是否重啟。SA_INTERRURT 不重啟。 SA_RESTART 重啟。

sa_flags 還有很多可選參數,適用于不同情況。如:捕捉到信號后,在執行捕捉函數期間,不希望自動阻塞該 信號,可將 sa_flags 設置為 SA_NODEFER,除非 sa_mask 中包含該信號。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383231.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383231.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383231.shtml

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

相關文章

Linu系統編程---10(Linux的終端,線路規程,網絡終端,進程組)

終端 輸入輸出設備的總稱 在 UNIX 系統中&#xff0c;用戶通過終端登錄系統后得到一個 Shell 進程&#xff0c;這個終端成為 Shell 進程的控制終端&#xff08;Controlling Terminal&#xff09;&#xff0c; 進程中&#xff0c;控制終端是保存在 PCB 中的信息&#xff0c;而 …

PCRE函數簡介和使用示例

PCRE是一個NFA正則引擎&#xff0c;不然不能提供完全與Perl一致的正則語法功能。但它同時也實現了DFA&#xff0c;只是滿足數學意義上的正則。 PCRE提供了19個接口函數&#xff0c;為了簡單介紹&#xff0c;使用PCRE內帶的測試程序(pcretest.c)示例用法。 1. pcre_compile 原型…

Linux系統編程---11(會話,守護進程,創建守護進程)

會話 創建會話 創建一個會話需要注意以下6點注意事項 調用進程不能是進程組組長&#xff0c;該進程變成新會話首進程該進程成為一個新進程組的組長進程需要root權限&#xff08;nbuntu不需要&#xff09;新會話丟棄原有的控制終端&#xff0c;該會話沒有控制終端該調用進程是…

判斷一段文件是UTF-8編碼還是GB2312的編碼方式

分類&#xff1a; 算法 cpp2012-03-10 16:01 7120人閱讀 評論(2) 收藏 舉報null生活c對于只包含中文和英文的文本中判斷編碼方式是非常簡單的&#xff0c;中文的編碼方式最常用的是GBK&#xff0c;字符集更大的如GBK向下兼容GB2312&#xff0c;其中包含的的很多一部分字符是我們…

判斷文件的編碼方式

/*功能&#xff1a;實現文件編碼格式的判斷通過一個文件的最前面三個字節&#xff0c;可以判斷出該的編碼類型&#xff1a;ANSI&#xff1a;        無格式定義&#xff1b;(第一個字節開始就是文件內容)Unicode&#xff1a;       前兩個字節為FFFE&#xff1b;…

Linux系統編程----12(線程概念,Linux線程實現原理,棧中ebp指針和ebp指針,線程的優缺點和共享資源)

線程概念 什么是線程 在一個程序里的一個執行路線就叫做線程&#xff08;thread&#xff09;。更準確的定義是&#xff1a;線程是“一個進程內部的控制序列” 一切進程至少都有一個執行線程線程在進程內部運行&#xff0c;本質是在進程地址空間內運行在Linux系統中&#xff0…

Linux系統編程---13(線程控制函數,創建線程,循環創建多個線程,線程間共享全局變量)

線程控制 操作系統并沒有提供創建線程的系統調用接口&#xff0c;因此大佬們封裝了一個線程的接口庫實現線程控制。意為著用戶創建線程都使用的是庫函數&#xff08;所以有時候我們說創建的線程是一個用戶態線程&#xff0c;但是在內核中對應有一個輕量級進程實現線程程序的調…

Linux系統編程---14(回收子線程,回收多個子線程,線程分離,殺死線程)

回收子線程 pthread_join 函數 阻塞等待線程退出&#xff0c;獲取線程退出狀態 其作用&#xff0c;對應進程中 waitpid() 函數。 int pthread_join (pthread_t thread,void** retval); 成功&#xff1a;0&#xff0c;失敗&#xff1a;錯誤號 參數&#xff1a;thread&#x…

Linux系統編程----15(線程與進程函數之間的對比,線程屬性及其函數,線程屬性控制流程,線程使用注意事項,線程庫)

對比 進程 線程 fork pthread_create exit (10) pthread_exit &#xff08;void *&#xff09; wait (int *) pthread_join &#xff08;&#xff0c;void **&#xff09;阻塞 kill pthread_cancel ();必須到取消點&#xff08;檢查點&#xff09;&#xff1a;…

內核雙向循環鏈表

#include <string.h>#include <stdio.h>#include <stdlib.h>#include<malloc.h>#include <arpa/inet.h>//鏈表頭結構struct list_head{struct list_head *next,*prev;};//真正實現鏈表插入操作void _list_add(struct list_head *nnew,struct lis…

Linux系統編程----16(線程同步,互斥量 mutex,互斥鎖的相關函數,死鎖,讀寫鎖)

同步概念 所謂同步&#xff0c;即同時起步&#xff0c;協調一致。不同的對象&#xff0c;對“同步”的理解方式略有不同。如&#xff0c;設備同步&#xff0c;是指在兩 個設備之間規定一個共同的時間參考&#xff1b;數據庫同步&#xff0c;是指讓兩個或多個數據庫內容保持一致…

轉移字符的轉換

使得網頁上不會顯示 \x0a\x0a \x0a \x0a \x0a \x0a 類似的字符static int te_escape_isDec(char *ptr, unsigned int len) { …

Linux系統編程---17(條件變量及其函數,生產者消費者條件變量模型,生產者與消費者模型(線程安全隊列),條件變量優點,信號量及其主要函數,信號量與條件變量的區別,)

條件變量 條件變量本身不是鎖&#xff01;但它也可以造成線程阻塞。通常與互斥鎖配合使用。給多線程提供一個會合的場所。 主要應用函數&#xff1a; pthread_cond_init 函數pthread_cond_destroy 函數pthread_cond_wait 函數pthread_cond_timedwait 函數pthread_cond_signa…

好友

http://blog.csdn.net/liangyuannao/article/details/8583139

Linux系統編程---18(線程池相關概念及其實現)

線程池 概念&#xff1a; 一堆線程任務隊列 作用 避免大量線程頻繁的創建/銷毀時間成本避免瞬間大量線程創建耗盡資源&#xff0c;程序崩潰危險 實現 創建固定數量的線程創建一個線程安全的任務隊列 一種線程使用模式。 線程過多會帶來調度開銷&#xff0c;進而影響緩…

設計模式--1(設計模式基礎,設計模式基本原則,設計模式分類)

設計模式基礎 模式 在一定環境中解決某一問題的方案&#xff0c;包括三個基本元素–問題&#xff0c;解決方案和環境。大白話&#xff1a;在一定環境下&#xff0c;用固定套路解決問題。 設計模式 是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使…

source insight 使用技巧

source insight 使用技巧 1 sourceinsight screen font 的默認字體是Verdana的&#xff0c;它是一直變寬字體。在Document style中可以將字體改為定寬的Courier2 document options->auto indent 去掉indent Open Brace和Indent Close Brace的效果: 繼上一段&#xff0c;在…

設計模式----2(簡單工廠模式的概念,簡單工廠模式的實現,簡單工廠模式的優缺點)

簡單工廠模式 簡單工廠模式的概念 簡單工廠模式屬于類的創建型模式,又叫做靜態工廠方法模式。通過專門定義一個類來負 責創建其他類的實例&#xff0c;被創建的實例通常都具有共同的父類。 具體分類 工廠&#xff08;Creator&#xff09;角色 簡單工廠模式的核心&#xff0…

Redis常見問題及其一些重點知識總結

1、什么是 Redis&#xff1f;簡述它的優缺點&#xff1f; Redis 的全稱是&#xff1a;Remote Dictionary.Server&#xff0c;本質上是一個 Key-Value 類型的內存數據庫&#xff0c;很像 memcached&#xff0c;整個數據庫統統加載在內存當中進行操作&#xff0c;定期通過異步操…

shell生成隨機文件名

1 #!/bin/bash 2 # tempfile-name.sh: 臨時文件名產生器 3 4 BASE_STRmcookie # 32-字符的 magic cookie. 5 POS11 # 字符串中隨便的一個位置. 6 LEN5 # 取得 $LEN 長度連續的字符串. 7 8 prefixtemp # 最終的一個臨時文…