Linux信號:信號的保存

目錄

一、信號在內核中的表示

?二、sigset_t

2.1sigset_t的概念和意義

2.2信號集操作數

三、信號集操作數的使用

3.1sigprocmask

3.2sigpending

3.3sigemptyset

四、代碼演示


一、信號在內核中的表示

實際執行信號的處理動作稱為信號 遞達(Delivery)
信號從產生到遞達之間的狀態,稱為信號 未決(Pending)
進程可以選擇 阻塞 (Block ) 某個信號。
被阻塞的信號產生時將保持在未決狀態,直到進程解除對此信號的阻塞,才執行遞達的動作。
注意,阻塞和忽略是不同的,只要信號被阻塞就不會遞達,而忽略是在遞達之后可選的一種處理動作。
信號在內核中的表示示意圖
每個信號都有兩個標志位分別表示阻塞(block)和未決(pending),還有一個函數指針表示處理動作。信號產生時,內核在進程控制塊中設置該信號的未決標志,直到信號遞達才清除該標志。在上圖的例子中
如上圖所示:
SIGHUP信號未阻塞也未產生過,當它遞達時執行默認處理動作。
SIGINT信號產生過,但正在被阻塞,所以暫時不能遞達。雖然它的處理動作是忽略,但在沒有解除阻塞之前不能忽略這個信號,因為進程仍有機會改變處理動作之后再解除阻塞。
SIGQUIT信號未產生過,一旦產生SIGQUIT信號將被阻塞,它的處理動作是用戶自定義函數sighandler。
如果在進程解除對某信號的阻塞之前這種信號產生過多次,將如何處理?POSIX.1允許系統遞送該信號一次或多次。Linux是這樣實現的:常規信號在遞達之前產生多次只計一次,而實時信號在遞達之前產生多次可以依次放在一個隊列里。

?二、sigset_t

2.1sigset_t的概念和意義

Linux中,常用的信號有31個,內核中則存在一個類似于位圖的方式來對該進程的block,peding進行表示,由于不存在0號信號,所以信號就從1號位置開始到31,如果該位置上為1則表示該信號當前存在,為0則表示不存在。

從上圖來看,每個信號只有一個bit的未決標志,非0即1,不記錄該信號產生了多少次,阻塞標志也是這樣表示的。
因此,未決和阻塞標志可以用相同的數據類型sigset_t來存儲,sigset_t稱為信號集,這個類型可以表示每個信號的“有效”或“無效”狀態,在阻塞信號集中“有效”和“無效”的含義是該信號是否被阻塞,而在未決信號集中“有效”和“無效”的含義是該信號是否處于未決狀態。下一節將詳細介紹信號集的各種操作。 阻塞信號集也叫做當前進程的信號屏蔽字(Signal Mask),這里的“屏蔽”應該理解為阻塞而不是忽略。
而為了方便統一管理,和安全性考慮,Linux中就設置了一種sigset_t的類型專門用于表示信號集。

2.2信號集操作數

sigset_t類型對于每種信號用一個bit表示“有效”或“無效”狀態,至于這個類型內部如何存儲這些bit則依賴于系統實現,從使用者的角度是不必關心的,使用者只能調用以下函數來操作sigset_ t變量,而不應該對它的內部數據做任何解釋,比如用printf直接打印sigset_t變量是沒有意義的。
而常用的系統調用接口有如下幾個:
#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset (sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);
函數sigemptyset初始化set所指向的信號集,使其中所有信號的對應bit清零,表示該信號集不包含 任何有效信號。
函數sigfillset初始化set所指向的信號集,使其中所有信號的對應bit置位,表示 該信號集的有效信號包括系統支持的所有信號。
注意,在使用sigset_ t類型的變量之前,一定要調 用sigemptyset或sigfillset做初始化,使信號集處于確定的狀態。初始化sigset_t變量之后就可以在調用sigaddset和sigdelset在該信號集中添加或刪除某種有效信號。

三、信號集操作數的使用

3.1sigprocmask

調用函數 sigprocmask 可以讀取或更改進程的信號屏蔽字 ( 阻塞信號集)。
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 
返回值:若成功則為0,若出錯則為-1
如果oset是非空指針,則讀取進程的當前信號屏蔽字通過oset參數傳出。如果set是非空指針,則 更改進程的信號屏蔽字,參數how指示如何更改。如果oset和set都是非空指針,則先將原來的信號 屏蔽字備份到oset里,然后根據set和how參數更改信號屏蔽字。假設當前的信號屏蔽字為mask,下表說明了how參數的可選值。
如果調用sigprocmask解除了對當前若干個未決信號的阻塞,則在sigprocmask返回前,至少將其中一個信號遞達。

3.2sigpending

#include <signal.h>sigset_t pendig;
int n=sigpending(&pending);
讀取當前進程的未決信號集,通過set參數傳出。調用成功則返回0則n=0,出錯則返回-1則n=-1。

3.3sigemptyset

清空sigset_t類型內部的數據。

sigset_t pending;
sigemptyset(&pending);
考慮到各個平臺的不同,這種方式可以很好解決在棧上生成隨機值的情況

四、代碼演示

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cassert>
#include <sys/wait.h>void PrintSig(sigset_t &pending)
{std::cout << "Pending bitmap: ";for (int signo = 31; signo > 0; signo--){if (sigismember(&pending, signo))//判斷該信號是否在信號集中{std::cout << "1";}else{std::cout << "0";}}std::cout << std::endl;
}void handler(int signo)
{sigset_t pending;sigemptyset(&pending);int n = sigpending(&pending); // 正在處理2號信號assert(n == 0);// 3. 打印pending位圖中的收到的信號std::cout << "遞達中...: ";PrintSig(pending); // 0: 遞達之前,pending 2號已經被清0. 1: pending 2號被清0一定是遞達之后std::cout << signo << " 號信號被遞達處理..." << std::endl;
}int main()
{// 對2號信號進行自定義捕捉 --- 不讓進程因為2號信號而終止signal(2, handler);// 1. 屏蔽2號信號sigset_t block, oblock;sigemptyset(&block);sigemptyset(&oblock);sigaddset(&block, 2); // SIGINT --- 根本就沒有設置進當前進程的PCB block位圖中// 0. for test: 如果我屏蔽了所有信號呢???// for(int signo = 1; signo <= 31; signo++) // 9, 19號信號無法被屏蔽, 18號信號會被做特殊處理//     sigaddset(&block, signo); // SIGINT --- 根本就沒有設置進當前進程的PCB block位圖中// 1.1 開始屏蔽2號信號,其實就是設置進入內核中int n = sigprocmask(SIG_SETMASK, &block, &oblock);assert(n == 0);// (void)n; // 騙過編譯器,不要告警,因為我們后面用了n,不光光是定義std::cout << "block 2 signal success" << std::endl;std::cout << "pid: " << getpid() << std::endl;int cnt = 0;while (true){// 2. 獲取進程的pending位圖sigset_t pending;sigemptyset(&pending);n = sigpending(&pending);assert(n == 0);// 3. 打印pending位圖中的收到的信號PrintSig(pending);cnt++;// 4. 解除對2號信號的屏蔽if (cnt == 20){std::cout << "解除對2號信號的屏蔽" << std::endl;n = sigprocmask(SIG_UNBLOCK, &block, &oblock); // 2號信號會被立即遞達, 默認處理是終止進程assert(n == 0);}// 我還想看到pending 2號信號 1->0 : 遞達二號信號!sleep(1);}return 0;
}

通過以上代碼所演示的現象我們也可以驗證兩個結論:

1、遞達信號的時候一定會把對應的pending位圖清0。

2、先清0,再遞達。

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

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

相關文章

Mysql數據庫——DML操作

目錄 添加數據&#xff08;INSERT&#xff09; 修改數據&#xff08;UPDATE&#xff09; 刪除數據&#xff08;DELETE&#xff09; 添加數據&#xff1a; &#xff08;1). 給指定字段添加數據 &#xff08;2). 給全部字段添加數據 &#xff08;3). 批量添加數據 修改數據: 案例…

【STM32】HAL庫點燈

【STM32】HAL庫點燈 一、探究目標二、探究原理2.1 ST開發庫2.1.1 直接配置寄存器2.1.2 標準外設庫2.1.3 HAL庫2.2 HAL開發2.2.1 環境配置2.2.2 時鐘配置2.2.3 GPIO配置2.2.4 工程創建2.2.5 KEIL代碼![在這里插入圖片描述](https://img-blog.csdnimg.cn/direct/bf1c95d5c6724a6a…

NextGen Mirth Connect XStream反序列化遠程代碼執行漏洞(CVE-2023-43208)

0x01 產品簡介 NextGen Mirth Connect是是美國NextGen公司的一個醫療集成引擎,主要用于醫療領域的系統集成和數據交換,支持多種協議和標準。 0x02 漏洞概述 NextGen Mirth Connect 4.4.1之前版本存在遠程代碼執行漏洞,未經身份認證的攻擊者可利用該漏洞遠程執行代碼。 0…

混合組網VS傳統網絡:智能硬件混合組網優劣勢淺要解析

智能硬件混合組網是一種利用多種通信技術相結合的方法&#xff0c;以實現更靈活、更可靠的網絡連接。通過藍牙、Wi-Fi、LoRa、4G相互之間的不同通訊方式&#xff0c;根據應用場景的不同以及現場實際環境&#xff0c;優選最佳物聯網混合組網方案&#xff0c;以達到部署最便捷性價…

一張SSL證書如何同時保護多個域名及其子域名?

在互聯網時代&#xff0c;數據安全和隱私保護變得至關重要&#xff0c;而SSL證書作為確保網站安全的重要工具&#xff0c;其重要性不言而喻。本文將詳細探討一種特殊的SSL證書——多域名通配符SSL證書&#xff0c;它為網站管理員提供了一種高效、經濟的方式來保護多個域名及其子…

學Java以及IDEA工具中遇到的常用單詞

Arithmetic 算術 operator 運算符 relational 關系 logic 邏輯 assign 分配 TernaryOperator 三元運算符、 gender 性別 lebal 標簽 array 數組 two dimesional 二維 object 對象 method 方法 row 行 column 列 parameter 參數 recursion 遞歸 overload 方法重載 calculate 計算…

MyBatis從入門到“入土“

&#x1f495;喜歡的朋友可以關注一下&#xff0c;下次更新不迷路&#xff01;&#x1f495;(●?●) 目錄 一、Mybatis為何物&#xff1f;&#x1f44c; 二、快速入門&#x1f923; 1、新建項目&#x1f60a; 2、數據庫建表&#x1f60a; 3、導入依賴的jar包&#x1f60a;…

Linux學習筆記6

TFTP 服務器搭建和測試 關于TFTP:TFTP&#xff08;Trivial File Transfer Protocol&#xff0c;簡單文件傳輸協議&#xff09;&#xff0c;是一個基于UDP 協議實現 的用于在客戶機和服務器之間進行簡單文件傳輸的協議&#xff0c;適合于開銷不大、不復雜的應用場合 搭建服務器…

后量子密碼的發展和應用

后量子算法&#xff0c;特別是后量子密碼(PQC)&#xff0c;是近年來密碼學領域的一個熱門話題。隨著量子計算技術的快速發展&#xff0c;傳統的公鑰密碼算法面臨著被量子計算機破解的威脅。為了應對這一挑戰&#xff0c;后量子密碼應運而生&#xff0c;成為了一種能夠抵抗量子計…

【論文筆記】| 蛋白質大模型ProLLaMA

【論文筆記】| 蛋白質大模型ProLLaMA ProLLaMA: A Protein Large Language Model for Multi-Task Protein Language Processing Peking University Theme: Domain Specific LLM Main work&#xff1a; 當前 ProLLM 的固有局限性&#xff1a;&#xff08;i&#xff09;缺乏自然…

Redis篇 在linux系統上安裝Redis

安裝Redis 在Ubuntu上安裝Redis 在Ubuntu上安裝Redis 在linux系統中,我們安裝Redis,必須先使它有root權限. 那么在linux中,如何切換到root用戶權限呢? sudo su 就可切換到用戶權限了. 在切換到用戶權限后,我們需要用一條命令來搜索Redis相關的軟件包 apt search redis 會出現非…

ROS2學習——節點話題通信(2)

目錄 一、ROS2節點 1.概念 2.實例 &#xff08;1&#xff09;ros2 run &#xff08;2&#xff09;ros2 node list &#xff08;3&#xff09;remapping重映射 &#xff08;4&#xff09;ros2 node info 二、話題 &#xff08;1&#xff09; ros2 topic list &#xf…

頭歌openGauss-存儲過程第1關:創建存儲過程

編程要求 1、創建第1個存儲過程&#xff0c;并調用&#xff1b; 1&#xff09;創建存儲過程&#xff0c;查詢emp表數據&#xff1b; 2&#xff09;調用存儲過程&#xff1b; --創建存儲過程&#xff0c;獲得計算機&#xff08;cs&#xff09;系學生選課情況并將結果寫入臨時表t…

人臉識別:基于卷積神經網絡(CNN)分類思想的人臉識別系統

本文來自公眾號 “AI大道理” —————— 項目配套視頻課程&#xff1a; 平臺&#xff1a;荔枝微課 鏈接&#xff1a;十方教育 項目地址&#xff1a;https://github.com/AIBigTruth/CNN_faces_recognition 之前很多人來詢問這個項目怎么做&#xff0c;代碼跑不起來&#…

數據庫讀寫分離

實現 MySQL 的讀寫分離主要可以通過以下幾種方式&#xff1a; 一主多從架構&#xff1a; 設置一個主數據庫&#xff08;Master&#xff09;來處理寫操作&#xff08;如 INSERT、UPDATE、DELETE&#xff09;。 設置多個從數據庫&#xff08;Slave&#xff09;來處理讀操作&…

USB數據恢復軟件:輕松找回U盤重要數據!

USB數據丟失的原因 USB數據丟失有一些常見原因&#xff0c;了解這些原因有利于恢復數據。 文件意外刪除病毒攻擊軟件錯誤未安全彈出USB設備格式化USB設備 順便一提&#xff0c;如果你通過快捷鍵“Ctrl D”刪除了數據&#xff0c;那你可以從回收站中還原它們。如果你永久刪除…

Isaac Sim仿真平臺學習(1)認識Isaac Sim

0.前言 上一個教程中我們下載好了Isaac Sim&#xff0c;這一章我們將來簡單了解一下Isaac Sim平臺。 isaac Sim仿真平臺安裝-CSDN博客 1.Isaac Sim是啥&#xff1f; What Is Isaac Sim? — Omniverse IsaacSim latest documentation Isaac Sim是NVDIA Omniverse平臺的機器…

【編譯原理復習筆記】屬性文法

屬性文法 也稱為屬性翻譯文法&#xff0c;由 Knuth 提出&#xff0c;以上下文無關文法為基礎 &#xff08;1&#xff09;為每個文法符號&#xff08;終結符與非終結符&#xff09;配備相關的屬性&#xff0c;代表與該文法符號相關的信息 &#xff08;2&#xff09;屬性文法對于…

【LSTM】基于Matlab的LSTM模型建模(代碼)

訓練目標&#xff1a;用LSTM訓練數據 數據&#xff1a;隨時間遞增&#xff0c;患者患病的概率&#xff08;橫坐標1個單位代表1個時間單位&#xff09; 以下代碼可直接運行 clc clear close all warning off % 關閉報警信息 %% 1.數據操作 % 1.1.導入數據&#x…

數據鏈路層協議——以太網協議

1. 數據鏈路層 網絡層用于將數據從一臺主機發送到另一臺主機。傳輸層用于將數據可靠的從一臺主機發送到另一臺主機。&#xff08;網絡層沒有保證可靠性的策略&#xff0c;傳輸過程中可能會出現各種意外&#xff0c;例如&#xff1a;丟包&#xff0c;網絡擁塞等。通過傳輸層可以…