sigfillset 函數詳解

sigfillset 函數詳解

一、函數概念

sigfillset() 是 POSIX 信號處理中的核心函數,用于初始化并填充一個信號集,使其包含當前系統支持的所有信號。它是操作信號屏蔽字(signal mask)的基礎工具,常與 sigprocmask()sigsuspend() 等函數配合使用。

關鍵特性:
  • 初始化信號集:將 sigset_t 類型變量設為包含所有信號
  • 原子操作:保證線程安全
  • 不可阻塞信號:對 SIGKILLSIGSTOP 無效(這兩個信號永遠不可阻塞)

二、函數原型和頭文件

#include <signal.h>int sigfillset(sigset_t *set);
參數:
  • set:指向要填充的信號集的指針
返回值:
  • 成功:返回 0
  • 失敗:返回 -1 并設置 errno(通常是 EFAULT,表示無效指針)

三、信號集(sigset_t)詳解

信號集是用于表示一組信號的數據類型,本質是位掩碼(bitmask)。在 Linux 中通常定義為:

typedef struct {unsigned long sig[_NSIG_WORDS];
} sigset_t;
信號范圍:
  • 標準信號:1~31(如 SIGINT=2, SIGSEGV=11
  • 實時信號:32~64(SIGRTMINSIGRTMAX

使用 kill -l 命令可查看系統支持的信號列表


四、使用場景

1. 阻塞所有信號
sigset_t all_signals;
sigfillset(&all_signals);  // 填充所有信號// 設置進程信號屏蔽字
sigprocmask(SIG_SETMASK, &all_signals, NULL);
2. 安全臨界區保護
void critical_section() {sigset_t old_set, new_set;// 準備阻塞所有信號sigfillset(&new_set);// 進入臨界區前阻塞信號sigprocmask(SIG_SETMASK, &new_set, &old_set);/* 臨界區代碼(不會被任何信號中斷) */// 恢復原始信號屏蔽sigprocmask(SIG_SETMASK, &old_set, NULL);
}
3. 等待特定信號
sigset_t mask, original_mask;
sigfillset(&mask);          // 包含所有信號
sigdelset(&mask, SIGUSR1);  // 刪除 SIGUSR1// 阻塞除 SIGUSR1 外的所有信號
sigprocmask(SIG_SETMASK, &mask, &original_mask);// 等待 SIGUSR1 信號
sigsuspend(&mask);// 恢復原始信號屏蔽
sigprocmask(SIG_SETMASK, &original_mask, NULL);

五、完整使用示例

示例:安全信號處理框架
#include <signal.h>
#include <stdio.h>
#include <unistd.h>volatile sig_atomic_t flag = 0;void handler(int sig) {flag = 1;  // 僅設置標志(異步安全)
}int main() {// 配置信號處理struct sigaction sa;sa.sa_handler = handler;sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART;sigaction(SIGINT, &sa, NULL);// 準備信號集sigset_t all_signals, wait_mask;sigfillset(&all_signals);      // 包含所有信號sigemptyset(&wait_mask);       // 空信號集sigaddset(&wait_mask, SIGINT); // 只關注SIGINT// 阻塞除SIGINT外的所有信號sigset_t old_mask;sigprocmask(SIG_SETMASK, &all_signals, &old_mask);sigdelset(&all_signals, SIGINT); // 允許SIGINT傳遞while(1) {// 安全等待信號(原子操作)sigsuspend(&wait_mask);if(flag) {printf("Processing signal...\n");/* 安全處理邏輯(非異步安全函數放這里) */flag = 0;}}// 恢復原始信號屏蔽(實際不會執行到這里)sigprocmask(SIG_SETMASK, &old_mask, NULL);return 0;
}

六、相關函數對比

函數功能常見使用場景
sigfillset()填充所有信號到信號集初始化全局屏蔽
sigemptyset()清空信號集準備添加特定信號
sigaddset()添加單個信號到信號集自定義屏蔽組合
sigdelset()從信號集刪除單個信號允許特定信號通過
sigismember()檢查信號是否在集合中信號狀態判斷
sigprocmask()設置進程信號屏蔽字臨界區保護/信號阻塞
sigsuspend()臨時替換信號掩碼并等待信號原子等待操作

七、重要注意事項

  1. 信號集生命周期

    // 錯誤!未初始化信號集
    sigset_t set;
    sigprocmask(SIG_SETMASK, &set, NULL); // 未定義行為// 正確:必須顯式初始化
    sigset_t set;
    sigfillset(&set); // 或 sigemptyset(&set);
    
  2. 不可阻塞信號

    sigset_t set;
    sigfillset(&set);
    sigprocmask(SIG_SETMASK, &set, NULL);// 以下信號仍能終止進程
    kill(getpid(), SIGKILL); // 始終有效
    kill(getpid(), SIGSTOP); // 始終有效
    
  3. 線程安全

    • 在多線程環境中,使用 pthread_sigmask() 替代 sigprocmask()
    pthread_sigmask(SIG_SETMASK, &set, NULL);
    
  4. sigaction 協作

    struct sigaction sa;
    sa.sa_handler = handler;
    sigfillset(&sa.sa_mask);  // 執行處理函數時阻塞所有其他信號
    sa.sa_flags = 0;
    

八、錯誤處理

sigset_t signal_set;if (sigfillset(&signal_set) == -1) {perror("sigfillset failed");switch(errno) {case EFAULT:fprintf(stderr, "Invalid memory address\n");break;default:fprintf(stderr, "Unknown error\n");}exit(EXIT_FAILURE);
}

總結

sigfillset() 是 Linux 信號處理的基礎構建塊:

  1. 核心作用:快速初始化包含所有信號的信號集
  2. 典型應用
    • 創建全局信號屏蔽
    • 實現安全臨界區
    • 配合 sigsuspend() 實現原子等待
  3. 最佳實踐
    • 總是顯式初始化信號集
    • 結合 sigdelset() 實現精細控制
    • 在多線程程序中使用線程安全版本

掌握 sigfillset() 及其相關函數,是編寫健壯的信號處理代碼的關鍵一步。通過合理控制信號屏蔽,可以有效防止信號競爭條件和不可預知的中斷行為。

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

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

相關文章

Redis實戰(8) -- 分布式鎖Redission底層機制

介紹Redisson 是基于 Redis 實現的 Java 駐內存數據網格&#xff08;In-Memory Data Grid&#xff09;&#xff0c;提供了分布式和可擴展的 Java 數據結構&#xff0c;如分布式鎖、分布式集合等。【注意】如果需要重新實現redission&#xff0c;需要重新設置RedissionClient配置…

Linux基礎測試

linux基礎測試 一、環境準備 基礎環境信息 登錄用戶&#xff1a;root&#xff08;初始密碼&#xff1a;redhat&#xff09; 虛擬機啟動&#xff1a;登錄后執行 virt-manager&#xff0c;右鍵啟動 node1 和 node2 虛擬機 node1 信息&#xff1a;root 密碼為 redhat&#xf…

Linux中Docker Swarm實踐

一、部署前后分離使用你自己的自定義鏡像部署多個副本所有副本使用相同的配置和邏輯Nginx 做反向代理統一入口外部訪問形式如&#xff1a;http://your-domain/api/xxx1.1 建立私庫鏡像已構建并推送到可訪問的鏡像倉庫啟動 Docker Registry 容器docker run -d -p 5000:5000 --re…

Dash 中的 dcc.Clipboard 組件詳解:實現一鍵復制功能

dcc.Clipboard 是 Dash 核心組件庫中的一個實用工具&#xff0c;允許用戶將指定內容一鍵復制到系統剪貼板&#xff0c;極大提升用戶體驗。本文將深入解析該組件的用法、特性和實際應用場景。 一、組件核心功能與價值 dcc.Clipboard 解決了 Web 應用中的關鍵痛點&#xff1a; 簡…

初識C++類的6個默認成員函數

目錄 一、初始化和清理 二、拷貝復制 三、取地址重載 四、重要說明 五、注意事項 六、示例代碼 在C中&#xff0c;當一個類沒有顯式定義某些成員函數時&#xff0c;編譯器會自動生成6個默認成員函數。這些函數可以分為以下幾類&#xff1a; 一、初始化和清理 1、構造函數…

Spring事務失效場景?

題目詳細答案Spring事務失效的場景主要有以下幾種。非public方法使用Transactional場景描述&#xff1a;Spring事務管理是基于AOP實現的&#xff0c;而AOP對于JDK動態代理或CGLib動態代理只會代理public方法。如果事務方法的訪問修飾符為非public&#xff0c;SpringAOP無法正確…

1.電動汽車動力電池系統技術介紹與分類

1.電動汽車動力電池系統技術介紹與分類 1.1 電動汽車發展的三個 “黃金時代” 第一個黃金時代&#xff08;19 世紀末 - 20 世紀初&#xff09; 技術基礎&#xff1a;鉛酸蓄電池發明&#xff08;1859 年&#xff09;&#xff0c;推動電動三輪車&#xff08;1873 年&#xff09;、…

調用阿里云-阿里云百煉 AI

相關文檔&#xff1a;大模型服務平臺百煉控制臺 多輪對話&#xff1a;通義千問模型的多輪對話_大模型服務平臺百煉(Model Studio)-阿里云幫助中心 創建知識庫&#xff1a;大模型服務平臺百煉控制臺 創建智能體&#xff1a;大模型服務平臺百煉控制臺 點擊智能體發布后&#x…

Apache Flink:從實時數據分析到實時AI

引言歡迎踏上這段深入了解 Apache Flink 演進歷程的旅程&#xff0c;Apache Flink 是一項重新定義了實時數據處理的技術。本博客文章基于王峰&#xff08;阿里云開放數據平臺負責人、Apache Flink Committer&#xff09;在 2025 年 Flink Forward Asia 新加坡大會上的演講內容編…

oelove奧壹新版v11.7旗艦版婚戀系統微信原生小程序源碼上架容易遇到的幾個坑,避免遺漏參數白屏顯示等問題

oelove和 金媒我都用過一段時間&#xff0c;其中oelove 用的時間較多&#xff0c;也比較了解這個系統&#xff0c;這個系統比較不錯的就是小程序是原生的&#xff08;完全遵循微信開發者平臺規則非Uniapp&#xff09;開發的&#xff0c;原生小程序的特點就是兼容性好&#xff0…

行為模式-模板方法模式

定義&#xff1a;Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure.&#xff08;定義一個操作中的算法的框架&a…

Java集合遍歷練習題

以下是10道難度遞增的集合遍歷練習題&#xff0c;涵蓋List、Set、Map的各種遍歷方式&#xff0c;包含解題思路、代碼實現和輸出結果&#xff1a; 練習題1&#xff1a;基礎遍歷 - ArrayList的for-each遍歷 題目&#xff1a;創建一個存儲5個字符串的ArrayList&#xff08;元素為&…

深度學習·ZegclipClip-RC

Zegclip 獲取圖像的特殊編碼&#xff1a;使用prompt tuning的技術&#xff0c;目的是減少過擬合和計算量。調整文本編碼&#xff1a;使用RD關系描述符&#xff0c;將每一個文本對應的[cls] token和圖像對應的[cls] token作哈密頓積&#xff0c;最后文本[cls]token形式化任務 文…

Taro 擴展 API 深度解析與實戰指南

Taro 擴展 API 深度解析與實戰指南 Taro 作為一款優秀的多端開發框架&#xff0c;提供了一系列強大的擴展 API&#xff0c;這些 API 極大地提升了開發效率和應用的可維護性。本文將深入解析 Taro 的擴展 API&#xff0c;并根據其功能特性進行分類講解&#xff0c;幫助開發者更…

容器之王--Docker的部署及基本操作演練

1.2 部署docker 1.2.1 容器工作方法1.2.2 部署第一個容器 官方站點&#xff1a;https://docs.docker.com/ 1.2.2.1 配置軟件倉庫 ]# cd /etc/yum.repos.d ]# vim docker.repo [docker] name docker-ce baseurl https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/sta…

VFTO與局部放電-高壓設備絕緣系統的雙重挑戰與防護策略

目錄 引言VFTO的定義與形成機理VFTO對高壓設備絕緣系統的影響局部放電的危害與機制VFTO與局部放電的關聯性分析檢測與監測技術防護與抑制措施未來技術發展趨勢結論與展望引言 在現代電力系統中&#xff0c;超快速暫態過電壓&#xff08;Very Fast Transient Overvoltage, VFTO&…

Windows下Rust編碼實現MP4點播服務器

Rust編碼可以實現眾多簡潔、可靠、高效的應用&#xff0c;但語法邏輯要求嚴格&#xff0c;尤其是依賴庫的選擇調用&#xff0c;需要耐心堅持“推敲”。借助DeepSeek并反復編程調試和問答改進&#xff0c;可以最終得到完整有效的Rust編碼。下面分享Windows下Rust編碼實現MP4點播…

ubuntu-相關指令

1、串口1.1確認在系統中檢查設備是否正常加載&#xff0c;在終端輸入以下命令&#xff1a;way1&#xff1a;ll /dev | grep ttyUSB&#xff08;ll是LL的小寫&#xff09; way2&#xff1a;ll /dev | grep ttyACM way3&#xff1a;ll /dev | grep ttyCH343USB&#…

docker容器臨時文件去除,服務器容量空間

概述&#xff1a; 接到告警提醒&#xff0c;服務器容量不足&#xff0c;去查看了一下&#xff0c;發現確實100g左右容量已基本用完&#xff1b;分析&#xff1a; 1&#xff09;查看根目錄下哪些文件夾占用容量較大 使用命令“ du -ah --max-depth1 / ” 查看目標目錄下所有文件…

損耗對信號質量的影響

損耗通常分為介質損耗與導體損耗&#xff1a;介質損耗&#xff1a;介質被施加電場后介質內部帶電粒子在外加電場的作用力下進行微小移動介質損耗與頻率成正比導體損耗&#xff1a;導體由于存在電阻&#xff0c;在有電流流過時產生的熱量造成的損耗為導體損耗。同時&#xff0c;…