子進程信號處理

SIGCHLD 信號詳解?


?一、信號定義與作用?

?SIGCHLD? 是 UNIX/Linux 系統中由內核向父進程發送的信號,用于通知子進程的狀態變化(如終止、停止或恢復)?。其主要作用包括:

  1. ?回收子進程資源?:避免子進程終止后成為僵尸進程(Zombie Process)占用系統資源?。
  2. ?監控子進程狀態?:父進程可響應子進程的異常退出、暫停或恢復事件?。

?二、觸發條件?

當子進程發生以下狀態變化時,內核會向父進程發送 SIGCHLD 信號:

  1. ?正常終止或異常退出?(如調用?exit()?或被?SIGKILL?終止)?。
  2. ?被作業控制信號暫停?(如?SIGSTOPSIGTSTP)?。
  3. ?由暫停狀態恢復運行?(收到?SIGCONT?信號)?。

?信號編號?:17
?默認行為?:系統級忽略(不回收資源,可能導致僵尸進程)?。


?三、信號處理方式?

1. ?自定義信號處理函數?

父進程需注冊處理函數,通過?waitpid?回收子進程:

#include <signal.h>
#include <sys/wait.h> void handler(int sig) 
{int status;while (waitpid(-1, &status, WNOHANG) > 0); // 非阻塞回收所有終止子進程 
} int main() 
{signal(SIGCHLD, handler); // 注冊處理函數 //... 創建子進程 ... 
}
  • ?關鍵點?:
    • 使用?WNOHANG?標志循環調用?waitpid,防止多個子進程同時退出時信號丟失?。
    • 必須在創建子進程前注冊處理函數,避免競爭條件導致信號遺漏?。
2. ?顯式忽略信號(自動回收)?
signal(SIGCHLD, SIG_IGN); // 內核自動回收子進程資源
  • ?注意?:
    • 此為 Linux 特有行為,不符合 POSIX 標準,其他 UNIX 系統可能不支持?。
    • 子進程停止時不再發送信號(BSD 系統行為差異)?。

?四、注意事項與風險?

  1. ?信號不排隊問題?
    多個子進程同時退出可能僅觸發一次 SIGCHLD,處理函數需循環調用?waitpid?直至返回錯誤?。
  2. ?系統調用中斷?
    慢速系統調用(如?read)可能被信號中斷,需手動重啟或檢查?EINTR?錯誤碼?。
  3. ?高并發場景優化?
    服務器中頻繁的子進程退出可能影響性能,可通過忽略信號或批量回收策略優化?。

?五、典型應用場景?

  1. ?服務端進程監控?
    Web 服務器父進程捕獲子進程異常退出信號,實現自動重啟機制?。
  2. ?交互式 Shell 作業控制?
    Shell 通過 SIGCHLD 跟蹤后臺進程狀態(如?jobs?命令)?。

?跨系統差異提示?:

  • BSD 系統中設置?SA_NOCLDSTOP?標志后,子進程停止時不發送信號?。
  • Python 等語言的信號處理遵循操作系統實現,需注意接口兼容性?。

sigprocmask函數介紹

sigprocmask?是 UNIX/Linux 系統中用于管理進程信號屏蔽字的系統調用,通過控制信號的阻塞狀態實現關鍵代碼段的保護或信號同步。以下是其核心機制與應用詳解:


?一、函數原型與參數?

#include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
  • ?參數說明?
    • how:操作類型,可選值:
      • SIG_BLOCK:將?set?中的信號加入當前屏蔽集(阻塞)?。
      • SIG_UNBLOCK:從當前屏蔽集中移除?set?中的信號(解除阻塞)?。
      • SIG_SETMASK:直接替換當前屏蔽集為?set?指定的信號集?。
    • set:指向待操作的信號集,若為?NULL?則不修改屏蔽集?。
    • oldset:保存原屏蔽集,可為?NULL?。
  • ?返回值?:成功返回 0,失敗返回 -1 并設置?errno?。

?二、核心功能與原理?

  1. ?信號屏蔽機制?
    • 每個進程擁有獨立的信號屏蔽字(Signal Mask),決定哪些信號被臨時阻塞?。
    • 被阻塞的信號處于 ?未決(pending)? 狀態,直到解除阻塞后才會遞送?。
  2. ?不可阻塞的信號?
    • SIGKILL?和?SIGSTOP?無法被阻塞或忽略(強制終止/暫停進程)?。

?三、典型應用場景?

  1. ?保護臨界區代碼?
    阻塞信號防止中斷共享數據修改等關鍵操作?67。
    sigset_t mask; 
    sigemptyset(&mask); 
    sigaddset(&mask, SIGINT); 
    sigprocmask(SIG_BLOCK, &mask, NULL); // 阻塞SIGINT 
    /* 臨界區代碼 */ 
    sigprocmask(SIG_UNBLOCK, &mask, NULL); // 恢復
  2. ?多線程信號控制?
    結合?pthread_sigmask?實現線程級信號屏蔽?。
  3. ?與?sigsuspend?配合?
    臨時修改屏蔽字并掛起進程,等待特定信號?。

?四、注意事項?

  1. ?信號丟失風險?
    長時間阻塞可能導致非實時信號被丟棄?。
  2. ?異步信號安全?
    避免在信號處理函數中調用非安全函數(如?printf)?。
  3. ?多線程環境?
    sigprocmask?僅影響調用線程的屏蔽字,需使用?pthread_sigmask?控制進程級信號?。

?五、示例代碼?

以下代碼演示阻塞?SIGINT?并恢復原屏蔽集:

#include <signal.h>
#include <stdio.h>int main() {sigset_t new_mask, old_mask;sigemptyset(&new_mask);sigaddset(&new_mask, SIGINT);// 阻塞SIGINT并保存原屏蔽集if (sigprocmask(SIG_BLOCK, &new_mask, &old_mask) == -1) {perror("sigprocmask");return 1;}printf("SIGINT blocked. Press Ctrl+C to test.\n");sleep(5); // 模擬關鍵操作// 恢復原屏蔽集sigprocmask(SIG_SETMASK, &old_mask, NULL);printf("SIGINT unblocked.\n");return 0;
}

?邏輯流程?:
初始屏蔽集 →?SIG_BLOCK?→ 信號阻塞(pending)→?SIG_UNBLOCK/SIG_SETMASK?→ 恢復遞送?。

例:

static void
block_sigchild (void)
{sigset_t mask;int status;sigemptyset (&mask);sigaddset (&mask, SIGCHLD);if (sigprocmask (SIG_BLOCK, &mask, NULL) == -1)die_with_error ("sigprocmask");/* Reap any outstanding zombies that we may have inherited */while (waitpid (-1, &status, WNOHANG) > 0);
}

這段代碼實現了對?SIGCHLD?信號的阻塞和僵尸進程清理功能,主要用于防止子進程狀態變化干擾主程序執行。以下是分步解析:

  1. ?信號阻塞部分?

    • sigemptyset(&mask)?初始化空的信號集
    • sigaddset(&mask, SIGCHLD)?將?SIGCHLD?信號加入信號集
    • sigprocmask(SIG_BLOCK, &mask, NULL)?阻塞該信號,防止子進程退出中斷主流程
    • 若阻塞失敗調用?die_with_error?報錯退出
  2. ?僵尸進程清理部分?

    • while (waitpid(-1, &status, WNOHANG) > 0)?循環非阻塞地回收所有已終止子進程
    • WNOHANG?參數確保沒有僵尸進程時立即返回
    • 通過?status?參數丟棄子進程退出狀態(未處理)

典型應用場景:

  • 在守護進程或服務端程序中,避免子進程退出信號干擾主事件循環
  • 防止未處理的?SIGCHLD?導致大量僵尸進程積累

注意:

  • 該實現會丟棄所有子進程退出狀態,如需處理返回值需修改?waitpid?邏輯
  • 長期運行程序可能需要定期調用此函數清理新產生的僵尸進程

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

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

相關文章

WPF 項目設置應用程序圖標和設置程序集圖標

在 WPF 項目中更改生成的可執行文件&#xff08;.exe&#xff09;圖標需要完成兩個關鍵步驟&#xff1a;設置應用程序圖標和設置程序集圖標。以下是詳細操作指南&#xff1a; 第一步&#xff1a;準備圖標文件 準備一個 .ico 格式的圖標文件&#xff08;必須使用 ICO 格式&…

JMeter壓測黑馬點評優惠券秒殺的配置及請求爆紅問題的解決(詳細圖解)

目錄 一、前言 二、優惠券秒殺壓測配置 三、已配置token但是請求全部爆紅的問題 四、配置JSON斷言后的效果 一、前言 在學習黑馬點評優惠券秒殺功能的壓力測試時&#xff0c;由于老師沒有任何引導而是直接開始測試&#xff0c;所以本博客記錄一下JMeter壓測黑馬點評優惠券秒…

Nginx 運維實戰: 什么是反向代理,如何配置?

在互聯網的龐大架構中&#xff0c;Nginx 作為一款高性能的 Web 服務器和反向代理服務器&#xff0c;發揮著至關重要的作用。其中&#xff0c;反向代理功能更是 Nginx 被廣泛應用的核心原因之一。本文將深入探討什么是反向代理&#xff0c;以及如何在 Nginx 中進行反向代理的配置…

短視第三套多功能主題3.0二開模板蘋果CMS插件重構版

這款短視第三套多功能主題二開模板蘋果CMS插件重構版源碼&#xff0c;基于市面上現有的二開版本進行的重制修正更新。目前已經完美適配新版 4049 以上的蘋果Cms系統&#xff0c;無需擔心因系統版本問題導致的不兼容情況。?主題插件重構后支持一鍵啟動插件自動安裝模板&#xf…

詳解力扣高頻SQL50題之1148. 文章瀏覽 I【入門】

傳送門&#xff1a;1148. 文章瀏覽 I 題目 Views 表&#xff1a; ---------------------- | Column Name | Type | ---------------------- | article_id | int | | author_id | int | | viewer_id | int | | view_date | date | ---------------------- 此表可能會存在重復…

內外網互傳文件 安全、可控、便捷的跨網數據交換

內外網互傳文件 安全、可控、便捷的跨網數據交換破解企業數字化痛點&#xff0c;重新定義文件傳輸標準在數字化轉型浪潮中&#xff0c;企業面臨著前所未有的挑戰&#xff1a;內網系統需要嚴密防護&#xff0c;外網協作又要高效便民。如何在網絡安全與業務效率之間找到完美平衡&…

性能監控裝飾器-python

看項目時&#xff0c;發現一個性能監控裝飾器&#xff0c;感覺挺有意思的。于是借鑒了他的思路&#xff0c;自己重新寫了我認為更簡潔的代碼。作用&#xff1a;可以放在類上和方法上&#xff0c;如果放在類上&#xff0c;則監控所有方法。根據設置的閾值&#xff0c;判斷方法執…

qt常用控件-05

文章目錄qt常用控件-05LineEditTextEditcombo box結語很高興和大家見面&#xff0c;給生活加點impetus&#xff01;&#xff01;開啟今天的編程之路&#xff01;&#xff01; 今天我們進一步c11中常見的新增表達 作者&#xff1a;?( ‘ω’ )?260 我的專欄&#xff1a;qt&am…

Python進階知識之pandas庫

目錄 一、Series&#xff1a;一維帶標簽的數組 二、DataFrame&#xff1a;二維表格型數據結構 三、Series 的核心操作 四、 DataFrame 的核心操作 五、 索引的特殊用法 六、 loc 與 iloc&#xff1a;DataFrame 的高級查詢 七、綜合案例 一、Series&#xff1a;一維帶標簽…

【GIT】基礎知識及基本應用

很高興為您詳細介紹Git的相關知識。Git是一個分布式版本控制系統&#xff0c;常用于軟件開發中的代碼管理和協作。以下是關于Git的一些基礎知識&#xff1a;1. 安裝和配置安裝&#xff1a;Windows&#xff1a;可以從GitHub下載適用于Windows的安裝包。MacOS&#xff1a;可以通過…

Maven Scope標簽:解鎖Java項目依賴管理的秘密武器

一、Maven 與依賴管理簡介在 Java 項目開發的龐大體系中&#xff0c;Maven 堪稱基石般的存在&#xff0c;發揮著極為關鍵的作用。它遵循 “約定優于配置” 的理念&#xff0c;讓項目的構建過程變得規范有序、結構化且具備良好的重復性 。比如&#xff0c;它強制執行標準的項目結…

IP43半加固筆記本L156H

IP43半加固筆記本L156H 產品特性&#xff1a;● 標配Intel I7-7700HQ 4核8線程處理器 ● 操作系統支持Windows7/10 64bit / Li n u x ● DDR4 16G 高速內存 zui高支持64G ● 全高清顯示面板15.6寸&#xff0c;1920X1080 ● 內置海德射頻模塊SMA接口 ● 工作溫度&#xff1a;…

ZooKeeper 是什么?

ZooKeeper 是一個分布式協調服務&#xff0c;由 Apache 基金會開發&#xff0c;專為分布式系統設計。它提供了高可用、高性能、一致性的核心服務&#xff0c;幫助分布式應用解決諸如配置管理、命名服務、分布式鎖、集群協調等問題。ZooKeeper 的核心特點&#xff1a;簡單易用&a…

Java學習第六十三部分——K8s

目錄 &#x1f4eb; 一、關鍵概述 &#x1f50d; ??二、定義起源?? &#x1f680; ??三、核心特點?? &#x1f3d7;? ??四、核心組件?? &#x1f9e9; ??五、資源對象?? ? ??六、應用場景?? &#x1f9f1; ??七、Java與K8s &#x1f6e0;? ?…

【自用】JavaSE--階段測試

考試題目第一題&#xff08;10分&#xff09;需求目前有100名囚犯&#xff0c;每個囚犯的編號是1-200之間的隨機數。現在要求依次隨機生成100名囚犯的編號&#xff08;要求這些囚犯的編號是不能重復的&#xff09;&#xff0c;然后讓他們依次站成一排。(注&#xff1a;位置是從…

Vulnhub Matrix-Breakout-2-Morpheus靶機攻略

1.下載靶機 靶機下載地址&#xff1a;https://download.vulnhub.com/matrix-breakout/matrix-breakout-2-morpheus.ova 下載后使用VM打開&#xff0c;后續選擇安裝地址開啟就算是下載好了 2.主機發現 查看網絡適配器模式&#xff08;NET模式&#xff09;&#xff0c;找到NET…

OpenCV —— 繪制圖形

&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?Take your time ! &#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?…

RHCE(4)

主&#xff1a;從&#xff1a;

網絡安全作業三

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>用戶登錄</title><link rel"style…

深入理解 ThreadLocal:從原理到最佳實踐

&#x1f4dd; 前言&#xff1a;為什么你需要了解 ThreadLocal&#xff1f;在多線程并發編程中&#xff0c;線程安全始終是一個繞不開的話題。我們常常需要為每個線程維護一份獨立的上下文數據&#xff0c;例如用戶信息、事務 ID、日志追蹤 ID 等。這些數據不能被多個線程共享&…