Linux學習:信號的保存

目錄

  • 1. 進程的異常終止與core dump標志位
    • 1.1 進程終止的方式
    • 1.2 core方案的作用與使用方式
  • 2. 信號的保存
    • 2.1 信號的阻塞
    • 2.2 操作系統中的sigset_t信號集類型
    • 2.3 進程PCB中修改block表的系統調用接口
    • 2.4 信號阻塞的相關問題驗證

1. 進程的異常終止與core dump標志位

1.1 進程終止的方式

??進程的終止方式大體可以分為兩種,正常終止異常終止。這兩種進程終止方式的不同會表現在進程的退出碼上,進程終止退出時會返回一個int類型的變量。此變量中只有低16bit位會被利用起來存儲信息,具體存儲方式如下:
在這里插入圖片描述
??當進程正常結束,進程的退出碼會寫在次低8bit位(16 ~ 8之間)的范圍中(下標從0開始),退出碼會表示進程退出的狀態。而當進程被信號終止,異常退出時,退出碼的低7bit位(7 ~ 0之間)的范圍內會寫入進程收到的信號。

??而信號異常終止的情況又被分為兩種,分別為Term方案與Core方案處理:

  • term方案(termination): 直接退出,然后進程釋放其的占用的資源
  • core方案: 被稱之為核心轉儲,將核心信息轉移儲存到生成的Core文件中,此文件存儲著進程異常終止的錯誤信息(發生了什么錯誤,導致錯誤發生的代碼是哪一行),便于后續排查錯誤。
    ??哪種信號導致的進程終止會使用哪個方案,可使用指令man 7 signal瀏覽手冊,查看具體信息。
    在這里插入圖片描述
    ??退出碼的第8個bit位,則是表示此進程的退出是否為core退出,值為1表示是,值為0表示否。當core方案默認沒有打開時,core退出的信號最后的退出方式也是term,core dumped位為0。

觀察異常退出進行的退出碼:

//打開core方案
int main()
{pid_t pid = fork();if(pid == 0){int a = 10;a /= 0;exit(0);}int status = 0;pid_t rid = waitpid(pid, &status, 0);if(rid ==  pid){cout << "exit code : " << ((status >> 8) & 0xFF) << endl;//退出碼 0cout << "exit signal : " << ((status) & 0x7F) << endl;	 //退出信號 SIGFPE : 8cout << "core dump : " << ((status >> 7) & 0x1) << endl; //core dump位 1cout << "status : " << status << endl;}return 0;
}

1.2 core方案的作用與使用方式


以下進行試驗與得出的結論都是基于Ubuntu 20.04 LTS系統版本
在這里插入圖片描述

core模式的打開與關閉:
??云服務器中,core模式是被默認關閉的,在想要使用core退出之前,需要先將core模式打開。當前進行的版本中,必須先執行sudo bash -c "echo core.%p > /proc/sys/kernel/core_pattern"指令,后續才能打開core模式。

  • 指令ulimit -a 查看core方案是否打開
    在這里插入圖片描述
  • 指令ulimit -c file-size 設置core文件的大小,當core文件大小不為0時,core模式就被打開了。舊版內核中,只有root用戶才能夠執行此條命令,而新版本內核中則沒有此限制
    在這里插入圖片描述
  • 指令ulimit -c 0 將core文件的大小設置為0時,core模式就會被關閉

core退出后core文件的使用方式:
??當進程因為收到core方案退出的信號而終止后,會打印出錯誤類型,錯誤信息后帶注釋信息(core dumped)。然后會生成一個core文件,core文件一般會有兩種,core文件或core.pid文件。
在這里插入圖片描述
??當進程core方案退出后,生成了對應的core文件后,我們就可以在Linux下的gdb調試工具中,通過core-file core/core.pid的方式,查看core文件中的異常錯誤信息。此種core文件協助調試的方式,被稱之為事后調試

在這里插入圖片描述


云服務器默認與重啟后關閉core退出的原因:
??云服務器一般都是會一直運行的,以此來持續給客戶端提供各種服務。當然,在此過程中會有程序異常中斷的可能。

    1. 但因為一些服務程序的重要性,不能使其因為中斷就一直停止運行。
    1. 所以,云服務器上的重要服務異常中斷時,會使用軟件方式讓其自動重啟,以求讓其能夠正常給大部分客戶端提供服務。
    1. 可若是云服務器默認打開了core異常退出方案的設置,在不斷重啟程序的過程中,就會導致生成大量的core.pid文件,最后就會使得服務器的磁盤被打滿服務器最后整個崩潰

??在版本的較新的內核中,會將core方案退出生成的文件都命名為core。這樣即使服務不斷重啟,每次生成的core文件也只會不斷覆蓋,core文件始終只存在一份。服務器也就不會因此而導致崩潰。

2. 信號的保存


概念補充:

  • 信號被進程接收后進行處理,信號的處理也被稱之為信號遞達
  • 信號從產生到遞達之間的狀態,被稱為信號未決

2.1 信號的阻塞

1. 信號阻塞的概念:
??操作系統中,進程可以選擇對指定的信號進行阻塞,也可以稱之為屏蔽。被阻塞的信號,即使被進程接收保存,也不會被進程處理。如果一個信號被阻塞,則該信號永遠也不會被遞達,除非進程對指定信號解除阻塞。進程PCB中存在著一個變量int block,此變量實際上是一張位圖,此位圖中的bit位都代指著一種信號,bit位的位置表示信號的編號,bit位的內容則是標識著進程對此信號是否屏蔽若bit位的值是1,則表示進行了屏蔽,若值是0,則表示沒有進行屏蔽
??對應信號的處理方法,在進程PCB中也有對應的一個函數指針數組handler_t* handler做存儲與管理。再綜合之前信號產生中的知識,進程存儲信號的pending位圖。可以得知,操作系統中,進程PCB對于信號的阻塞、保存、處理分別都有一張表用于描述與管理。
在這里插入圖片描述
2. 信號的忽略與阻塞:
??信號的阻塞與忽略并不是一種行為,對信號進行阻塞,進程是無法識別到有對應的信號到了,所以也就不會做出響應處理。而信號的忽略,則是進程已經識別到了信號,但對信號采用了忽略這一處理方式,所以,表現出的現象就是進程什么都沒有做。總而言之,阻塞就是進程沒有識別到信號,而忽略則是進程識別到了但什么都不做。
??當信號被阻塞屏蔽時,此種信號在一段時間內大量的被發送給此進程。對于普通信號pending表中只會存儲一個,在接觸阻塞之后,進程只會對最近的一次信號做處理。而對于實時信號,在遞達之前同種信號產生多次,則是會依次放在一個隊列里,此處不做詳細討論。

2.2 操作系統中的sigset_t信號集類型

??操作系統中,用戶是不能對系統的內核資源直接做修改的,只能通過操作系統提供系統調用接口來間接達成修改的目的。block信號阻塞表就屬于操作系統的內核資源,操作系統對此提供了專用的用戶級數據類型sigset_t與系統調用接口。sigset_t也被稱為信號集
??此類型為操作系統提供的位圖類型,創建一個此類型變量修改其中內容并配合相應的系統調用接口就可以達到對block表的修改,即控制進程阻塞哪些信號。此外,sigset_t類型同樣可以用于接收pending表中的內容,以此來達到讓用戶查看pending的目的。sigset_t類型相關的系統調用接口具體如下:

  • 1. 將sigset_t變量內容置0
#include <signal.h>
int sigemptyset(sigset_t* set);
  • 2. 將所有bit位都設置為1(用于阻塞所有信號)
int sigfillset(sigset_t* set);
  • 3. 將指定bit位設置為1(用于阻塞指定信號)
int sigaddset(sigset_t* set, int signo);
  • 4. 將指定bit位設置為0(用于解除阻塞信號)
int sigdelset(sigset_t* set, int signo);
  • 5. 用于查看信號集中是否存在某個信號(配合查看pending表)
int sigismember(const sigset_t* set, int signo);

2.3 進程PCB中修改block表的系統調用接口

#include <signal.h>//signal mask信號屏蔽字
int sigprocmask(int how, const sigset_t* set, sigset_t* oldset);
  • 參數1int how 系統內置宏參數,用于指定調用接口的模式
宏常量作用
SIG_BLOCK將 set 中的信號添加到當前信號屏蔽字中(阻塞這些信號)
SIG_UNBLOCK將 set 中的信號從當前信號屏蔽字中移除(解除阻塞)
SIG_SETMASK將當前信號屏蔽字直接設置為 set(完全覆蓋)
  • 參數2const sigset_t* set block表修改的新參考信號集
  • 參數3sigset_t* oldset 被修改前的就信號集

??sigset_t信號集在不同平臺下的實現方式不同,此系統內置類型不支持cout流插入或printf直接打印。sigset_t信號集被定義與修改好后,并沒有直接達到修改block表的效果,需要配合sigprocmask接口才能真的將數據設置進內核。

2.4 信號阻塞的相關問題驗證

  • 問題1:如果一個進程將所有信號都進行屏蔽,那么這個進程是否就無法被外部終止了

??驗證方式: 創建一個死循環的進程,使用系統調用接口讓此進程屏蔽所有信號,最后讓其運行起來。待其運行之后,再使用指令對此進程嘗試一個一個發出所有信號,觀察進程反應。進程運行時,可以循環打印自己的pending表,當表bit位為1時,表示著進程收到了信號,但信號并沒有被處理,這代表信號成功被阻塞。

實驗代碼:

void PrintPending()
{sigset_t sig;sigemptyset(&sig);sigpending(&sig);for(int i = 31; i > 0; i--){if(sigismember(&sig, i)){cout << "1";}else{cout << "0";}}cout << " , pid is : " << getpid() << endl;
}int main()
{sigset_t sig;sigemptyset(&sig);for(int i = 1; i <= 31; i++)sigaddset(&sig, i);int n = sigprocmask(SIG_SETMASK, &sig, nullptr);assert(n == 0);(void)n;//如此強轉,是因為在release版本下,變量n后續若是沒有使用編譯器會報警cout << "signal mask success..." << endl;while(true){PrintPending();sleep(1);}return 0;
}

驗證結果:
??進程運行后,使用指令c=1; while [ $c -le 31 ]; do kill -$c pid; echo kill -$c; let c++; sleep 1; done發送信號,觀察現象。
在這里插入圖片描述
??運行程序執行指令后,可以發現,9號信號被發送后成功遞達,SIGKILL:9號信號并不能被屏蔽。
在這里插入圖片描述
??跳過9號信號之后繼續驗證其他信號,由運行結果發現SIGSTOP:19號信號也沒有被屏蔽。而18號信號雖然能夠正常屏蔽,但屏蔽18號信號之后又會導致一些已經被屏蔽的信號接觸阻塞。
??操作系統如此設置的原因,是為了預防出現非法的病毒進程將自己的所有信號都設置阻塞,導致操作系統無法殺死病毒進程。


問題2:操作系統中進程在進行遞達操作時,是先將pending表中的信號bit位清0,還是先執行handler處理函數

??驗證方法: 自定義一個信號的遞達處理函數handler,讓其在handler函數查看當前進程的pending表中的對應信號bit位。若pending表中的對應信號bit位清0了,代表清0操作于handler方法之前執行,若bit位置未清0,則代表清0操作于handler方法之后。

驗證代碼:

void handler(int signo)
{sigset_t sig;sigemptyset(&sig);sigpending(&sig);if(sigismember(&sig, signo)){cout << "先執行handler" << endl;}else{cout << "先清0" << endl;}
}int main()
{signal(SIGINT, handler);while(true){cout << "process pid is : " << getpid() << endl;sleep(1);}return 0;
}

驗證結果:先清0
在這里插入圖片描述

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

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

相關文章

數據分析編程第二步: 最簡單的數據分析嘗試

2.1 數據介紹有某公司的銷售數據表 sales.csv 如下:第一行是標題&#xff0c;解釋每一列存了什么東西。第二行開始每一行是一條數據&#xff0c;對應一個訂單。這種數據有個專業的術語&#xff0c;叫結構化數據。這是現代數據處理中最常見的數據類型。整個表格的數據統稱為一個…

UDP報文的數據結構

主要內容參照https://doc.embedfire.com/net/lwip/zh/latest/doc/chapter14/chapter14.html#id6&#xff0c;整理出來自用。 1. UDP 報文首部結構體&#xff08;udp_hdr&#xff09; 為清晰定義 UDP 報文首部的各個字段&#xff0c;LwIP 設計了udp_hdr結構體&#xff0c;其包含…

圖論與最短路學習筆記

圖論與最短路在數學建模中的應用 一、圖論模型圖 G(V,E)G(V,E)G(V,E) VVV&#xff1a;頂點集合EEE&#xff1a;邊集合每條邊 (u,v)(u,v)(u,v) 賦予權值 w(u,v)w(u,v)w(u,v)&#xff0c;可用 鄰接矩陣 或 鄰接表 表示。二、最短路問題的數學形式 目標&#xff1a;尋找從源點 sss…

第九節 Spring 基于構造函數的依賴注入

當容器調用帶有一組參數的類構造函數時&#xff0c;基于構造函數的 DI 就完成了&#xff0c;其中每個參數代表一個對其他類的依賴。接下來&#xff0c;我們將通過示例來理解 Spring 基于構造函數的依賴注入。示例&#xff1a;下面的例子顯示了一個類 TextEditor&#xff0c;只能…

【數據庫】PostgreSQL詳解:企業級關系型數據庫

文章目錄什么是PostgreSQL&#xff1f;核心特性1. 標準兼容性2. 擴展性3. 高級功能4. 可靠性數據類型1. 基本數據類型2. 高級數據類型基本操作1. 數據庫操作2. 表操作3. 數據操作高級查詢1. 連接查詢2. 子查詢3. 窗口函數JSON操作1. JSON數據類型2. JSON查詢3. JSON索引全文搜索…

FFMPEG相關解密,打水印,合并,推流,

1&#xff1a;ffmepg進行打水印解密 前提ffmepg安裝利用靜態版就可以這個什么都有&#xff0c;不用再配置其他信息&#xff1a;&#xff08;這個利用ffmpeg終端命令是沒問題的&#xff0c;但是如果要是再C中調用ffmpeg庫那么還需要從新編譯安裝下&#xff09; 各個版本 Inde…

MySql知識梳理之DML語句

注意: 插入數據時&#xff0c;指定的字段順序需要與值的順序是一一對應的。 字符串和日期型數據應該包含在引號中。 插入的數據大小&#xff0c;應該在字段的規定范圍內注意:修改語句的條件可以有&#xff0c;也可以沒有&#xff0c;如果沒有條件&#xff0c;則會修改整張表的所…

GaussDB GaussDB 數據庫架構師修煉(十八)SQL引擎-SQL執行流程

1 SQL執行流程查詢解析&#xff1a;詞法分析、語法分析、 語義分析 查詢重寫&#xff1a;視圖和規則展開、基于規則的查詢優化 計劃生成&#xff1a;路徑搜索和枚舉、選出最優執行計劃 查詢執行&#xff1a;基于優化器生成的物理執行計劃對數據進行獲取和計算2 解析器和優化器S…

grpc 1.45.2 在ubuntu中的編譯

要在 Ubuntu 上編譯 gRPC 1.45.2&#xff0c;需要按照以下步驟操作。以下指南基于 gRPC 官方文檔和相關資源&#xff0c;確保環境配置正確并成功編譯。請確保你有管理員權限&#xff08;sudo&#xff09;以安裝依賴項和執行相關命令。 1. 準備環境 確保你的 Ubuntu 系統已安裝…

lesson45:Linux基礎入門指南:從內核到實踐操作全解析

目錄 一、Linux簡介與核心概念 1.1 Linux的起源與發展 1.2 內核與發行版的關系 二、Linux內核版本解析 2.1 內核版本命名規則 2.2 2025年主流內核版本 三、主流Linux發行版對比 3.1 桌面用戶首選 Ubuntu 24.04 LTS Linux Mint 22 3.2 技術愛好者之選 Fedora 41 Ar…

PCL點云庫入門(第24講)——PCL庫點云特征之NARF特征描述 Normal Aligned Radial Feature(NARF)

一、算法原理 1、NARF 特征概述 NARF(Normal Aligned Radial Feature)是 2011 年由 Bastian Steder 等人在論文 《Point Feature Extraction on 3D Range Scans Taking into Account Object Boundaries》中提出的一種 稀疏局部 3D 特征描述子。 核心目標是提取具有“邊界意…

使用 eventpp 構建跨 RT-Thread 與 ARM-Linux 的輕量級 Active Object(AO)事件驅動框架

0. 引言 本文展示一個實踐路徑&#xff1a;以輕量級 C 事件庫 eventpp 為核心&#xff0c;設計并實現一個面向嵌入式的、可移植的 Active Object&#xff08;AO&#xff09;事件驅動架構。該架構滿足以下目標&#xff1a; 跨平臺兼容&#xff1a;單套代碼在 RT-Thread&#xff…

【python實用小腳本-193】Python全能PDF小助手:剪切/合并/旋轉/加密一條龍——再也不用開會員

Python全能PDF小助手&#xff1a;剪切/合并/旋轉/加密一條龍——再也不用開會員 PDF編輯, 本地處理, 零會員費, 多功能腳本, 瑞士軍刀 故事開場&#xff1a;一把瑞士軍刀救了周五下班的你 周五 17:55&#xff0c;老板甩來一堆 PDF&#xff1a; “把第 3、7 頁刪掉”“再和合同合…

Ubuntu根分區擴容

目錄 1.先查看/dev/sda 整塊磁盤設備的分區占用情況&#xff1a; 2.在VMware中編輯虛擬機&#xff1a; 3.進入虛擬機&#xff0c;進入disk應用程序&#xff1a; 4.擴容文件系統 5.最后通過df-h lsblk或通過可視化GParted進行驗證。 1.先查看/dev/sda 整塊磁盤設備的分區占…

智慧城市SaaS平臺/市政設施運行監測系統之空氣質量監測系統、VOC氣體監測系統、污水水質監測系統及環衛車輛定位調度系統架構內容

1. 空氣質量監測系統1) 監測點管理 a) 監測點基本信息 支持記錄空氣質量監測點的名稱、位置、類型、設備配置等信息。 b) 監測點分布地圖 支持通過GIS地圖展示監測點的分布情況&#xff0c;支持地圖查詢和導航。 2) 空氣質量監測 a) 實時數據采集 支持實時采集空氣質量數據&…

PiscCode迅速集成YOLO-Pose 實現姿態關鍵點軌跡跟蹤應用

在計算機視覺領域&#xff0c;人體姿態檢測與軌跡跟蹤是很多應用場景的核心技術&#xff0c;例如運動分析、行為識別、智能監控等。本文將介紹如何在 PiscCode 平臺上&#xff0c;利用 YOLO-Pose 模型進行姿態估計&#xff0c;并實現多人關鍵點軌跡跟蹤。 一、什么是 PiscCode …

HTTP的狀態碼有哪些,并用例子說明一下

問題HTTP的狀態碼有哪些&#xff0c;并用例子說明一下我的回答HTTP狀態碼是服務器對客戶端請求的響應碼&#xff0c;它們按照不同的功能被分為五大類。我來介紹一下主要的狀態碼及其實際應用場景&#xff1a;1xx&#xff08;信息性狀態碼&#xff09;&#xff1a;表示請求已接收…

【51單片機】【protues仿真】基于51單片機寵物投食器系統

目錄 一、主要功能 二、使用步驟 三、硬件資源 四、軟件設計 五、實驗現象 一、主要功能 1、LCD1602液晶顯示當前時間 2、按鍵設置時間&#xff0c;5個定時投喂時間? 3、可以通過手動按鍵進行投喂食物 4、步進電機模擬投喂食物 二、使用步驟 基于51單片機的寵物自動投…

掌握設計模式--命令模式

命令模式&#xff08;Command Pattern&#xff09; 命令模式&#xff08;Command Pattern&#xff09;是一種行為型設計模式&#xff0c;它將請求&#xff08;命令&#xff09;封裝成對象&#xff0c;從而使您能夠參數化客戶端&#xff08;調用者&#xff09;使用不同的請求、…

STM32之beep、多文件、延遲、按鍵以及呼吸燈

一、Beep控制 原理圖分析&#xff1a; 蜂鳴器三極管控制引腳對應 MCU PB8。當前蜂鳴器對應的電路中&#xff0c;三極管是 NPN 三極管&#xff0c;當前【基極】存在小電流&#xff0c;當前三極管導通。要求對應 PB8 引腳對外輸出電壓 / 電流。當前 PB8 輸出高電平&#xff0c;當…