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

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

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

一、信號發(fā)送

1、信號動(dòng)作

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

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

普通信號

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

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

實(shí)時(shí)信號

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

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

3、core dump

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

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

二、信號的保存

1、前置概念

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

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

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

2、阻塞信號

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

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

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

3、保存信號

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

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

實(shí)際上blockpending都屬于保存信號,只不過因?yàn)橛袃蓚€(gè)位圖,我們分開來說罷了

4、信號遞達(dá)

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

5、總結(jié)

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

三、信號集操作函數(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); 
// 判斷一個(gè)信號是否在信號集中,不在返回0,在返回1,出錯(cuò)返回-1

1、設(shè)置block位圖

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

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

返回值:若成功則為0,若出錯(cuò)則為-1

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

how 取值含義示例說明
SIG_BLOCK將 set 所指向的信號集中的信號添加到當(dāng)前的信號掩碼中,即阻塞 set 中的信號若當(dāng)前信號掩碼已阻塞 SIGINT,使用 SIG_BLOCK 并傳入包含 SIGTERM 的信號集,SIGTERM 也會(huì)被阻塞
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:指向一個(gè)sigset_t類型的信號集,該信號集包含了要操作的信號,如果how的值為SIG_BLOCKSIG_UNBLOCK,則set表示要添加或移除的信號集;如果how的值為SIG_SETMASK,則set表示要設(shè)置的新的信號掩碼,若該參數(shù)為NULL,則不改變當(dāng)前的信號掩碼,僅獲取當(dāng)前信號掩碼,此時(shí)oset不能為NULL

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

2、設(shè)置pending位圖

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

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

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

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

3、設(shè)置handler行為

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

四、驗(yàn)證信號保存行為

#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,此時(shí)2號信號被阻塞
    sigprocmask(SIG_SETMASK, &bset, &oset);

    // 重復(fù)打印當(dāng)前進(jìn)程的 pending 信號集,期間向進(jìn)程發(fā)送 2號信號
    // 因?yàn)?2號信號被阻塞了,所以 2號信號會(huì)一直被保存在 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秒后我們自動(dòng)放開阻塞,瞬間打印出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是一個(gè)自由和開放源代碼、高性能、分配的內(nèi)存對象緩存系統(tǒng)。用于加速動(dòng)態(tài)web應(yīng)用程序,減輕數(shù)據(jù)庫負(fù)載。
    2010-12-12
  • Linux二進(jìn)制方式部署MinIO的完整步驟

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

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

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

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

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

    在Ubuntu上開啟SSH遠(yuǎn)程登錄的步驟如下:檢查SSH安裝情況、啟動(dòng)SSH服務(wù)、設(shè)置開機(jī)啟動(dòng)、檢查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腳本的三種實(shí)現(xiàn)方式

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

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

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

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

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

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

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

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

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

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

最新評論

塔河县| 高唐县| 涡阳县| 崇州市| 吴旗县| 雷波县| 融水| 武定县| 海口市| 清丰县| 时尚| 杨浦区| 余姚市| 望奎县| 开化县| 随州市| 莎车县| 平遥县| 宁蒗| 霞浦县| 财经| 盐山县| 衡山县| 霍州市| 农安县| 涞源县| 延边| 大邑县| 拜泉县| 正蓝旗| 安龙县| 大新县| 闻喜县| 通江县| 兖州市| 海门市| 武胜县| 五大连池市| 丰台区| 安福县| 政和县|