深入了解linux系統—— 進程信號的產生

前言

進程在收到信號之后,可以立即處理,也可以在合適的時間再處理(1-31號普通信號可以不被立即處理)

信號不是被立即處理,信號就要被保存下來,讓進程在合適的時間再去處理。

相關概念

在了解進程是如何保存信號之前,先了解一下一些概念:

  • 信號遞達:進程實際執行信號的處理動作
  • 信號未決:信號從產生到遞達的狀態
  • 阻塞:進程可以阻塞某一個信號;(被阻塞的信號不會被遞達,直到解除對信號的阻塞,該信號才會被遞達)
  • 忽略:是進程對于已遞達的信號的一種處理方式。

信號保存

進程要將信號保存下來,在合適的時候處理;保存信號不僅要保存是否存在信號,也要保存進程是否阻塞信號以及進程對于信號的處理方式。

Linux內核中,對于信號存在三張表分別是:blockpendinghandler;它們分別存儲了進程對于信號的阻塞信號,收到信號以及進程對于信號的處理方式。

每一個信號都有阻塞、未決兩個標識位以及處理動作,這分別和blockpendinghandler表一一對應。

  1. block表,表示進程對于信號的阻塞情況;
  2. pending表,表示處于未決的信號情況;
  3. handler表,函數指針表,存儲著進程對于信號的處理方式。

對于blockpending,可以簡單理解為位圖,對于1-31號信號,每一個信號對應一個bit位;

blockbit位為1表示進程阻塞該信號,pendingbit位為1表示該信號處于未決狀態(進程收到該信號)。

對于handler表,其存儲的是進程對于信號的處理方式。

在這里插入圖片描述

了解了信號的保存方式blockpendinghandler表;

那發送信號的本質就是將進程的task_struct中的pending表對應的bit位置1(修改內核數據結構對象)

進程處理信號本質就是檢查進程task_structblock表是否阻塞信號、pending表是否存在信號,然后進行調用handler表中進程對于信號的處理方法。

信號集sigset_t

信號保存的blockpending表,都是以位圖的方式來保存信號阻塞和未決的狀態;01

對于阻塞和未決標識都可以使用sigset_t(信號集)這一數據類型來存儲。

信號集sigset_t,可以表示信號有效無效的狀態。

在阻塞信號集中,有效無效表示信號是否被阻塞。

在未決信號集中,有效無效表示信號是否處于未決狀態。

信號集操作函數

對于sigset_t信號集,我們不清楚里面有什么;不能直接對信號集進程操作,需要用到特定的函數接口。

在這里插入圖片描述

相關信號集操作函數,例如初始化sigemptyset(設置為0)、sigfillset(設置為1)、sigaddset(新增信號)、sigdelset(刪除信號)等等。

初始化信號集

int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);

對于初始化信號集,分為兩種:一是所有bit位設置為0、二是所有bit位設置為1

sigemptyset,初始化信號集,所有bit位設置為0

sigfillset,初始化信號集,所有bit位設置為1

新增信號

int sigaddset(sigset_t* set, int signum);

在信號集中,新增一個信號signum

刪除信號

int sigdelsets(sigset_t* set, int signum);

在信號集set這,刪除信號signum

對于上述的sigemptysetsigfilletsigaddsetsigdelset,這些函數返回值:

如果函數調用成功,返回0

函數調用失敗,返回-1

判斷信號是否存在

int sigismember(sigset_t* set, int signum);

sigismember函數用來判斷信號集sig中是否存在信號signum

如果存在就返回1;如果不存在就返回0;如果函數調用失敗就返回-1

系統調用

上述信號集操作函數,是修改當前已有信號集sigset_t

而在Linux內核中,存在block表和pending表來記錄進程對于信號的屏蔽和未決狀態;那我們能否修改內核中的block表呢?能否獲取內核中的blockpending表呢?

當然是可以的,我們可以通過系統調用sigprocmasksigpending來對內核中進程的阻塞信號集未決信號集進行相關操作。

sigprocmask

調用該函數,可以修改或者讀取信號屏蔽字

int sigprocmask(int how, const sigset_t *_Nullable restrict set, sigset_t *_Nullable restrict oldset);

對于sigprocmask函數,一共存在三個參數:

第一個參數表示要對內核中的block(阻塞信號集)進行什么操作;how的取值如下圖:

在這里插入圖片描述

第二個參數set指向當前信號集,我們需要自己創建信號集;

第三個參數oldset是一個輸出型參數,當調用sigprocmask修改內核阻塞信號集時,會將內核阻塞信號集輸出到oldset指向的信號集中。

測試:這里簡單調用setprocmask為進程添加屏蔽2號信號

#include <stdio.h>
#include <signal.h>
#include <iostream>int main()
{sigset_t set;sigemptyset(&set);//初始化信號集sigaddset(&set, 2);//在信號集中添加2號信號sigset_t oldset;sigprocmask(SIG_BLOCK, &set, &oldset);while (true){}return 0;
}

在這里插入圖片描述

sigpending

int sigpending(sigset_t *set);

調用sigpending函數可以獲取進程的pending表(未決信號集)。

在內核中pending表是記錄進程2未決信號的狀態的,給進程發信號的本質就是修改內核中進程的pending表。

在獲取了進程的未決信號集之后,我們可以使用信號集相關操作函數來判斷該信號集中是否存在未決的信號。

這里簡單驗證:阻塞的信號是不會被遞達的;

void print_pending()
{// 獲取pendingsigset_t set;sigpending(&set);//輸出位圖for (int i = 31; i >= 1; i--){if (sigismember(&set, i))std::cout << '1';elsestd::cout << '0';}std::cout << std::endl;
}
void handler(int sig)
{std::cout << "receive sig : " << sig << std::endl;
}int main()
{//自定義捕捉2號信號signal(2, handler);//屏蔽2號信號sigset_t set, oldset;sigemptyset(&set);sigaddset(&set,2);sigprocmask(SIG_BLOCK, &set, &oldset);int cnt = 10;while(cnt--){//輸出pending表print_pending();if(cnt == 0){//解除對2號信號的屏蔽sigemptyset(&set);sigprocmask(SIG_SETMASK, &oldset,nullptr);}sleep(1);}return 0;
}

在這里插入圖片描述

總結

簡單總結上述內容:

信號保存:block信號屏蔽表、pending信號未決表、handler信號處理方式(函數指針表)

信號集sigset_t,相關操作:初始化、新增、刪除、判斷是否存在等等

系統調用:sigprocmask:獲取或設置內核blcok表、sigpending獲取內核pending表。

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

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

相關文章

【Bluedroid】藍牙協議棧enable流程深度解析

本文詳細剖析 Bluedroid 藍牙功能啟用的核心流程&#xff0c;從enable()函數觸發開始&#xff0c;深入解析藍牙協議棧的異步啟動機制、核心協議模塊初始化、硬件控制器綁定及狀態同步全流程。重點闡述接口就緒性檢查、異步線程管理、配置文件回調機制等關鍵環節&#xff0c;揭示…

各種開發語言主要語法對比

各類主流編程語言的語法有著顯著差異&#xff0c;這些差異源于語言設計哲學&#xff08;簡潔性 vs 顯式性&#xff09;、應用領域&#xff08;系統級、Web、數據科學&#xff09;、運行方式&#xff08;編譯 vs 解釋&#xff09;以及支持的范式&#xff08;面向對象、函數式、過…

小鵬汽車6月交付車輛34,611輛,同比增長224%

小鵬汽車-W(09868)發布公告&#xff0c;2025年6月&#xff0c;小鵬汽車共交付智能電動汽車34,611輛&#xff0c;同比增長224%&#xff0c;這標志著小鵬汽車已連續第八個月交付量超過了30,000輛。2025年第二季度&#xff0c;小鵬汽車共交付103,181 輛智能電動車&#xff0c;創下…

深入理解觀察者模式:構建松耦合的交互系統

在軟件開發中&#xff0c;我們經常遇到這樣的場景&#xff1a;一個對象的狀態變化需要通知其他多個對象&#xff0c;并且這些對象需要根據變化做出相應的反應。比如&#xff0c;用戶界面中的數據變化需要實時反映到多個圖表上&#xff0c;或者電商系統中的庫存變化需要通知訂單…

React強大且靈活hooks庫——ahooks入門實踐之常用場景hook

什么是 ahooks&#xff1f; ahooks 是一個 React Hooks 庫&#xff0c;提供了大量實用的自定義 hooks&#xff0c;幫助開發者更高效地構建 React 應用。其中場景類 hooks 是 ahooks 的一個重要分類&#xff0c;專門針對特定業務場景提供解決方案。 安裝 ahooks npm install …

Qt常用控件之QWidget(一)

Qt常用控件之QWidget&#xff08;一&#xff09;1.QWidget2.enabled屬性2.geometry&#x1f31f;&#x1f31f;hello&#xff0c;各位讀者大大們你們好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f680;系列專欄&#xff1a;【Qt的學習】 &#x1f4dd;&#x1f4dd;本…

AIOT開發選型:行空板 K10 與 M10 適用場景與選型深度解析

前言 隨著人工智能和物聯網技術的飛速發展&#xff0c;越來越多的開發者、學生和愛好者投身于創意項目的構建。 在眾多的開發板中&#xff0c;行空板 K10 和 M10 以其獨特的優勢脫穎而出。 本文旨在為讀者提供一份詳盡的行空板 K10 和 M10 對比分析&#xff0c;從適用場景、…

redis匯總筆記

語雀完整版&#xff1a; https://www.yuque.com/g/mingrun/embiys/calwqx/collaborator/join?tokensLcLnqz5Rv8hOKEB&sourcedoc_collaborator# 《Redis筆記》 Redis 一般問題 Redis內存模型&#xff08;I/O多路模型&#xff09;多路復用IO如何解釋 為什么Redis要使用單線…

STM32用PWM驅動步進電機

硬件介紹&#xff1a;連線&#xff1a;注意這里stp連的是pwm脈沖&#xff0c;dir連的是方向到時候代碼pwm波形就是從這里來的&#xff0c;具體接線根據你的代碼來注意要點&#xff1a;步進電機和舵機驅動是不一樣的&#xff0c;它是根據步長來移動的&#xff0c;所以要開一個中…

力扣25.7.10每日一題——重新安排會議得到最多空余時間 II

Description 今天這道題和昨天類似&#xff0c;只是允許順序變化。 Solution 把會議區間視作桌子&#xff0c;空余時間視作空位&#xff0c;我們要把一個桌子移到別的空位中。 初步想法是枚舉桌子&#xff0c;找一個長度大于等于桌子長度的空位移過去。看上去&#xff0c;找…

IP報文分片與重組原理及實現分析

IP報文分片與重組原理及實現分析 引用&#xff1a; ppp/net/packet/IPFragment.hppp/net/packet/IPFragment.cpp 1. IP分片原理 當IP數據包大小超過MTU&#xff08;最大傳輸單元&#xff09;時&#xff0c;路由器/主機將其分割為多個片段傳輸&#xff0c;每個片段包含&…

[python]在drf中使用drf_spectacular

安裝drf_spectacular 文檔 pypi鏈接:https://pypi.org/project/drf-spectacular/ 文檔鏈接:https://drf-spectacular.readthedocs.io/en/latest/readme.html 安裝步驟 在環境中添加 pip install drf-spectacular在setting的INSTALLED_APPS中添加 INSTALLED_APPS [# ALL…

【Datawhale AI 夏令營】 用AI做帶貨視頻評論分析(二)

5.預訓練模型跑分 回顧賽題 回顧賽題任務 挑戰與難點&#xff1a; 標注數據少 ——> 半監督學習 or 數據增強 聚類分析噪點影響嚴重 回顧Baseline 問題&#xff1a; TF-IDF無法捕捉以下語義。聚類分析粗糙&#xff0c;未評估聚類質量。 提升方案&#xff1a; 分類任務…

SPSSPRO:數據分析市場SaaS挑戰者的戰略分析

目錄 第一部分&#xff1a;執行摘要 第二部分&#xff1a;平臺解構&#xff1a;產品、架構與用戶體驗 2.1 SaaS范式轉移&#xff1a;架構與起源 2.2 功能能力&#xff1a;分析師的工具箱 2.3 “智能分析”的價值主張 第三部分&#xff1a;市場滲透與受眾細分 3.1 目標用戶…

低版本hive(1.2.1)UDF實現清除歷史分區數據

目標&#xff1a;通過UDF實現對表歷史數據清除 入參&#xff1a;表名、保留天數N 一、pom文件 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.…

C++中頂層const與底層const

在C中&#xff0c;const關鍵字用于定義常量&#xff0c;但它在指針和引用上下文中會產生兩種不同的常量性&#xff1a;頂層const&#xff08;top-level const&#xff09;和底層const&#xff08;low-level const&#xff09;。理解它們的區別是避免編譯錯誤和提高代碼質量的關…

“SRP模型+”多技術融合在生態環境脆弱性評價模型構建、時空格局演變分析與RSEI指數生態質量評價

集成云端、桌面端等環境&#xff0c;結合遙感云計算、GIS空間分析&#xff0c;R語言統計分析的優勢&#xff0c;以分析生態環境脆弱性的時空演變為主線。通過本課程的學習&#xff0c;您將掌握&#xff1a;第一&#xff0c;收集各類指標數據&#xff0c;構建的“生態壓力度-生態…

算法學習筆記:17.蒙特卡洛算法 ——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在計算機科學和數學領域&#xff0c;蒙特卡洛算法&#xff08;Monte Carlo Algorithm&#xff09;以其獨特的隨機抽樣思想&#xff0c;成為解決復雜問題的有力工具。從圓周率的計算到金融風險評估&#xff0c;從物理模擬到人工智能&#xff0c;蒙特卡洛算法都發揮著不可替代的作…

Tortoise 設置

如何關閉 Windows 下 TortoiseGit 任務欄里窗口標題的分支顯示 一、引言 TortoiseGit 是一個專為團隊協作設計的 Git 圖形化客戶端&#xff0c;旨在解決版本控制中常見的問題&#xff0c;如沖突、回滾、歷史查看等。本文檔是 TortoiseGit 的使用手冊前言部分&#xff0c;旨在向…

[論文閱讀] 人工智能 + 軟件工程 | AI助力軟件可解釋性:從用戶評論到自動生成需求與解釋

AI助力軟件可解釋性&#xff1a;從用戶評論到自動生成需求與解釋 Automatic Generation of Explainability Requirements and Software Explanations From User ReviewsarXiv:2507.07344 Automatic Generation of Explainability Requirements and Software Explanations From …