最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux進(jìn)程信號的發(fā)送和保存方法

 更新時間:2025年04月01日 10:36:15   作者:s_little_monster_  
從信號產(chǎn)生到信號保存,中間經(jīng)歷了很多,當(dāng)操作系統(tǒng)準(zhǔn)備對信號進(jìn)行處理時,還需要判斷時機是否 “合適”,在絕大多數(shù)情況下,只有在 “合適” 的時機才能處理信號,即調(diào)用信號的執(zhí)行動作,本文將給大家介紹Linux進(jìn)程信號的發(fā)送和保存方法,需要的朋友可以參考下

一、信號發(fā)送

1、信號動作

通過指令man -7 signal查看信號的手冊,然后往下翻翻可以看到普通信號發(fā)出后對應(yīng)的操作,以及它們的信號編號,和詳細(xì)描述信息

2、信號發(fā)送的本質(zhì)

普通信號

信號發(fā)送的本質(zhì)實際上是寫信號,把信號寫到進(jìn)程PCB結(jié)構(gòu)體對應(yīng)的位圖上去,在進(jìn)程的PCB中有這么一個位圖(是pending位圖,下面會說)正好對應(yīng)著我們從1 ~ 31的普通信號編號,收到哪個信號就將哪一位對應(yīng)的比特位置為1,表示收到信號,然后PCB再做對應(yīng)的工作

值得注意的是,如果連續(xù)發(fā)普通信號,那么進(jìn)程只會處理最后一次的信號,每次寫都是覆蓋寫的

實時信號

我們前面說過信號分為31個普通信號和31個實時信號,實時信號的作用類似于我們嵌入式RTOS實時運轉(zhuǎn)場景,要保持實時性,實時信號發(fā)送的本質(zhì)類似于普通信號,不過此時我們保存信號的載體不再是一個位圖,而是一個結(jié)構(gòu)體,它們被組織在信號隊列當(dāng)中,誰先發(fā)送誰就先入隊,隊列遵循先入先出的規(guī)則,所以先發(fā)送也代表著先被處理

值得注意的是,如果連續(xù)發(fā)實時信號,那么進(jìn)程會將隊列中的信號一個個全部處理

3、core dump

當(dāng)程序在運行過程中發(fā)生崩潰(如段錯誤、除零錯誤等),Core dump 會記錄下程序崩潰瞬間的內(nèi)存狀態(tài),包括寄存器的值、調(diào)用棧信息、全局變量和局部變量的值等,開發(fā)人員可以使用調(diào)試工具(如 GDB)加載 Core dump 文件,通過分析這些信息,準(zhǔn)確地找到程序崩潰的位置和原因

我們可以通過ulimit -c 10240將core文件的大小限制修改為10240字節(jié),出現(xiàn)錯誤的時候core文件可能瞬間會被打滿的,所以我們云服務(wù)器上一般默認(rèn)core文件的大小限制為0,我們要是用的話再修改它的大小限制即可
形成的文件叫做core.pid,pid就是出錯進(jìn)程的pid,假設(shè)test進(jìn)程出現(xiàn)錯誤,12314是它的pid,我們可以通過在gdb模式下輸入gdb test core.12314打印錯誤信息和原因

二、信號的保存

1、前置概念

實際執(zhí)行信號的處理動作稱為信號遞達(dá)

信號從產(chǎn)生到遞達(dá)之間的狀態(tài),稱為信號未決

被阻塞的信號產(chǎn)生是將保持在未決狀態(tài),直到進(jìn)程解除對此信號的阻塞,才執(zhí)行遞達(dá)的動作

2、阻塞信號

信號被阻塞就是將信號阻塞在信號未決狀態(tài),具體實現(xiàn)阻塞功能的,是一個位圖block

block是一個位圖,共31位,對應(yīng)1 ~ 31號信號,當(dāng)對應(yīng)比特位為1時,表示該編號信號被阻塞,為0則表示不阻塞

如果信號被阻塞則進(jìn)入阻塞態(tài),若沒有被阻塞那么信號進(jìn)入未決狀態(tài)

3、保存信號

未決狀態(tài)的作用就是保存信號,它保存信號的方式也是通過位圖pending

pending也是一個位圖,與block一致,對應(yīng)的下標(biāo)和信號編號也是一一對應(yīng),當(dāng)對應(yīng)比特位為1時,表示該編號信號處于未決狀態(tài),為0則信號遞達(dá)

實際上blockpending都屬于保存信號,只不過因為有兩個位圖,我們分開來說罷了

4、信號遞達(dá)

信號遞達(dá)后的信號,會執(zhí)行相對應(yīng)的行為,有SIG_DFL:默認(rèn)處理動作,SIG_IGN:忽略,和自定義處理sighandler,這在前面提到過

5、總結(jié)

一個信號,首先要經(jīng)過block,block為0來到pending,pending為0來到handler執(zhí)行動作,其中,9號和19號新號還是特例,它們是不能被阻塞和保存的,這兩個信號一旦發(fā)出就是直接handler,其實也不用handler了,它們對應(yīng)的不可能為忽略和信號捕捉后的自定義函數(shù),只能為默認(rèn)動作終止和暫停

三、信號集操作函數(shù)

信號集操作函數(shù)顧名思義就是操作信號集的函數(shù),sigset_t被稱作信號集,是操作系統(tǒng)提供的數(shù)據(jù)類型,用于描述位圖,下面就是信號集操作函數(shù)

#include <signal.h>

int sigemptyset(sigset_t *set); 
// 將位圖全部設(shè)置為 0

int sigfillset(sigset_t *set); 
// 將位圖全部都設(shè)置為 1

int sigaddset (sigset_t *set, int signo); 
// 將位圖中的某一位設(shè)置為 1

int sigdelset(sigset_t *set, int signo); 
// 將位圖中的某一位設(shè)置為 0

int sigismember(const sigset_t *set, int signo); 
// 判斷一個信號是否在信號集中,不在返回0,在返回1,出錯返回-1

1、設(shè)置block位圖

sigprocmask是一個在信號處理中非常重要的系統(tǒng)調(diào)用,主要用于檢查、修改進(jìn)程的信號掩碼(阻塞信號集)

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 

返回值:若成功則為0,若出錯則為-1

how:指定對信號掩碼的操作方式

how 取值含義示例說明
SIG_BLOCK將 set 所指向的信號集中的信號添加到當(dāng)前的信號掩碼中,即阻塞 set 中的信號若當(dāng)前信號掩碼已阻塞 SIGINT,使用 SIG_BLOCK 并傳入包含 SIGTERM 的信號集,SIGTERM 也會被阻塞
SIG_UNBLOCK從當(dāng)前的信號掩碼中移除 set 所指向的信號集中的信號,即解除對 set 中信號的阻塞若當(dāng)前信號掩碼阻塞了 SIGINT 和 SIGTERM,使用 SIG_UNBLOCK 并傳入包含 SIGINT 的信號集,SIGINT 信號的阻塞狀態(tài)將被解除
SIG_SETMASK將當(dāng)前的信號掩碼設(shè)置為 set 所指向的信號集,覆蓋原來的信號掩碼若原信號掩碼阻塞 SIGINT,使用 SIG_SETMASK 并傳入包含 SIGTERM 的信號集,信號掩碼將只阻塞 SIGTERM

set:指向一個sigset_t類型的信號集,該信號集包含了要操作的信號,如果how的值為SIG_BLOCKSIG_UNBLOCK,則set表示要添加或移除的信號集;如果how的值為SIG_SETMASK,則set表示要設(shè)置的新的信號掩碼,若該參數(shù)為NULL,則不改變當(dāng)前的信號掩碼,僅獲取當(dāng)前信號掩碼,此時oset不能為NULL

oset:指向一個sigset_t類型的信號集,用于存儲調(diào)用sigprocmask之前的信號掩碼,如果不需要保存舊的信號掩碼,可以將該參數(shù)設(shè)置為NULL

2、設(shè)置pending位圖

sigpending是一個用于獲取進(jìn)程當(dāng)前未決信號集的系統(tǒng)調(diào)用

#include <signal.h>
int sigpending(sigset_t *set);

返回值:成功返回0,失敗返回-1

setsigpending函數(shù)會將當(dāng)前進(jìn)程中處于未決狀態(tài)(即已發(fā)送但由于被阻塞而尚未被處理)的信號集存儲到set所指向的sigset_t對象中

3、設(shè)置handler行為

三種情況,默認(rèn),忽略和自定義,自定義那當(dāng)然是signal函數(shù),前面有,不再贅述

四、驗證信號保存行為

#include <iostream>
#include <signal.h>
#include <unistd.h>

using namespace std;
//打印出位圖
void PrintPending(const sigset_t &pset)
{
    for(int i = 31; i >= 1; i--)
    {
        cout << sigismember(&pset, i);
    }
    cout << endl;
}

void handler(int signum)
{
    cout << "catch a signum: " << signum << endl;
}

int main()
{
	//自定義捕捉2號信號
    signal(2, handler);

    sigset_t bset, oset; 
    sigemptyset(&bset); // bset信號集清空
    sigemptyset(&oset); // oset信號集清空
    sigaddset(&bset, 2); // 將bset的第2位設(shè)為1,也就是給bset中添加上2號信號

    // 調(diào)用系統(tǒng)調(diào)用,將數(shù)據(jù)設(shè)置進(jìn)內(nèi)核,設(shè)置block,此時2號信號被阻塞
    sigprocmask(SIG_SETMASK, &bset, &oset);

    // 重復(fù)打印當(dāng)前進(jìn)程的 pending 信號集,期間向進(jìn)程發(fā)送 2號信號
    // 因為 2號信號被阻塞了,所以 2號信號會一直被保存在 pending 中
    sigset_t pset; 
    sigemptyset(&pset);// pset信號集清空
    int cnt = 0;
    //在15秒內(nèi),未接受信號前,都是一直打印0
    while(true)
    {
         int n = sigpending(&pset);
         if(n < 0) continue;
         //打印位圖
         PrintPending(pset);
         sleep(1);
         cnt++;
         if(cnt == 15)
         {
            cout << "unblock 2 signo" << endl;
            // 打印15次位圖后解除阻塞
            sigdelset(&bset, 2);//將bset的第2位設(shè)置為0,也就是給bset去除2號新號,不阻塞2號
            //設(shè)置當(dāng)前信號屏蔽字為oset指向的值,也就是0
            sigprocmask(SIG_SETMASK, &oset, nullptr);
         }
    }

    return 0;
}

查看一下效果,在3秒后,我按下ctrl+c,然后我們的捕捉信號函數(shù)沒有工作,說明信號被阻塞了,然后15秒后我們自動放開阻塞,瞬間打印出handler函數(shù)定義要打印的信息,再按ctrl+c就正常進(jìn)行handler行為了

到此這篇關(guān)于Linux進(jìn)程信號的發(fā)送和保存方法的文章就介紹到這了,更多相關(guān)Linux進(jìn)程信號發(fā)送和保存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 網(wǎng)站加速VPS篇 memcache和memcached安裝方法

    網(wǎng)站加速VPS篇 memcache和memcached安裝方法

    Memcache是一個自由和開放源代碼、高性能、分配的內(nèi)存對象緩存系統(tǒng)。用于加速動態(tài)web應(yīng)用程序,減輕數(shù)據(jù)庫負(fù)載。
    2010-12-12
  • Linux二進(jìn)制方式部署MinIO的完整步驟

    Linux二進(jìn)制方式部署MinIO的完整步驟

    MinIO 是一個高性能、云原生的對象存儲解決方案,與 Amazon S3 API 兼容,本文將詳細(xì)介紹在 Linux 系統(tǒng)上部署 MinIO 的多種方式,涵蓋從單機部署到生產(chǎn)環(huán)境集群配置的完整流程,需要的朋友可以參考下
    2026-01-01
  • 在Linux中部署并初始化MySQL的多種方式

    在Linux中部署并初始化MySQL的多種方式

    MySQL是常用的關(guān)系型數(shù)據(jù)庫,被廣泛用于學(xué)習(xí)與實際工作中,本篇文章介紹在Linux系統(tǒng)中使用多種方式部署并初始化MySQL數(shù)據(jù)庫,包括源碼安裝、rpm安裝以及yum安裝,需要的朋友可以參考下
    2025-11-11
  • ubuntu如何開啟ssh遠(yuǎn)程登錄

    ubuntu如何開啟ssh遠(yuǎn)程登錄

    在Ubuntu上開啟SSH遠(yuǎn)程登錄的步驟如下:檢查SSH安裝情況、啟動SSH服務(wù)、設(shè)置開機啟動、檢查SSH狀態(tài)、配置防火墻、并使用SSH客戶端進(jìn)行遠(yuǎn)程登錄
    2025-03-03
  • Linux環(huán)境下查看日志文件命令詳解

    Linux環(huán)境下查看日志文件命令詳解

    大家好,本篇文章主要講的是Linux環(huán)境下查看日志文件命令詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Linux中執(zhí)行Shell腳本的三種實現(xiàn)方式

    Linux中執(zhí)行Shell腳本的三種實現(xiàn)方式

    這篇文章主要介紹了Linux中執(zhí)行Shell腳本的三種實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • CentOS7中防火墻的一些常用配置介紹

    CentOS7中防火墻的一些常用配置介紹

    centos 7中防火墻是一個非常的強大的功能了。這篇文章主要介紹了CentOS7中防火墻的一些常用配置,需要的朋友可以參考下
    2016-12-12
  • Apache下分析ab性能測試結(jié)果

    Apache下分析ab性能測試結(jié)果

    本文詳細(xì)講解了Apache下分析ab性能測試結(jié)果,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • Linux實現(xiàn)數(shù)據(jù)庫定時備份方式

    Linux實現(xiàn)數(shù)據(jù)庫定時備份方式

    這篇文章主要介紹了Linux實現(xiàn)數(shù)據(jù)庫定時備份方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • CentOS虛擬機忘記root密碼快速安全重置的全流程

    CentOS虛擬機忘記root密碼快速安全重置的全流程

    在本地使用虛擬機進(jìn)行測試時,長時間不登錄很容易忘記密碼,本文將詳細(xì)介紹如何通過GRUB引導(dǎo)參數(shù)修改,安全重置CentOS虛擬機的root密碼,本方法適用于CentOS 7/8/9及兼容系統(tǒng),需要的朋友可以參考下
    2025-09-09

最新評論

手机| 灌南县| 综艺| 绥德县| 巴南区| 上饶市| 中超| 宜城市| 松阳县| 泸州市| 华安县| 个旧市| 通河县| 渝北区| 江达县| 丹东市| 新丰县| 西乡县| 克什克腾旗| 乌海市| 台山市| 滨州市| 福贡县| 金平| 南陵县| 丰县| 阜阳市| 蓬溪县| 益阳市| 古田县| 武城县| 鄯善县| 靖江市| 东乡族自治县| 玉溪市| 高碑店市| 南充市| 梅州市| 内江市| 胶南市| 缙云县|