欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux中的信號(hào)(注冊(cè),注銷,處理,阻塞)

 更新時(shí)間:2024年02月12日 17:04:22   作者:風(fēng)吹雨淋  
這篇文章主要介紹了Linux中的信號(hào)(注冊(cè),注銷,處理,阻塞),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

未決:pending(漢語(yǔ)翻譯:待定,即將發(fā)生)

  • 信號(hào)產(chǎn)生但沒有被處理,pending表0變1,表示進(jìn)程收到對(duì)應(yīng)信號(hào)(準(zhǔn)確的來(lái)說(shuō)叫信號(hào)寫入)
  • 阻塞,為了攔截對(duì)應(yīng)信號(hào)做出對(duì)應(yīng)的處理動(dòng)作。不想處理某些信號(hào),攔不住別人給進(jìn)程發(fā)
  • 信號(hào)待定是可以隨時(shí)遞達(dá)(被處理),如果沒有被阻塞,信號(hào)會(huì)在合適的時(shí)候遞達(dá)(被處理)
  • 什么叫合適的時(shí)候:從內(nèi)核態(tài)切換到用戶態(tài)時(shí)進(jìn)行信號(hào)的檢測(cè)和處理
  • 如果信號(hào)阻塞,該信號(hào)永遠(yuǎn)處于未決狀態(tài)
  • 總之pending表就是隨時(shí)能處理信號(hào),一旦設(shè)置了阻塞,只有解除阻塞才能處理信號(hào)

信號(hào)注冊(cè)

信號(hào)注冊(cè):在進(jìn)程中做標(biāo)記,讓進(jìn)程能夠知道自己收到某個(gè)信號(hào),官方說(shuō)法操作系統(tǒng)內(nèi)核給進(jìn)程發(fā)送信號(hào)的過(guò)程,這個(gè)過(guò)程稱為注冊(cè)

  • PCB中有一個(gè)pending未決(沒有被處理)信號(hào)的集合(是一個(gè)位圖結(jié)構(gòu)),標(biāo)記進(jìn)程收到了某個(gè)信號(hào)
  • PCB中有一個(gè)sigqueue鏈表(實(shí)質(zhì)是一個(gè)雙向鏈表),進(jìn)程每收到一個(gè)信號(hào),就是給該鏈表中添加一個(gè)對(duì)應(yīng)信號(hào)的節(jié)點(diǎn),并且修改位圖,將信號(hào)值對(duì)應(yīng)位置置1

非可靠信號(hào)注冊(cè):

  • 如果沒有收到信號(hào)則注冊(cè)(添加節(jié)點(diǎn),位圖置1)
  • 如果之前收到了信號(hào)還未處理,則什么都不做(丟棄)

可靠信號(hào)注冊(cè):

  • 不管位圖是否置1(是否已經(jīng)注冊(cè),還沒處理),都會(huì)添加一個(gè)信號(hào)節(jié)點(diǎn)

可以通過(guò)sigqueue函數(shù)在發(fā)送信號(hào)的同時(shí)攜帶數(shù)據(jù)

信號(hào)注銷

什么是注銷:

  • 在信號(hào)被處理之前,消除信號(hào)存在的痕跡
  • 主要防止信號(hào)被重復(fù)處理

非可靠信號(hào)的注銷:

刪除信號(hào)的信息節(jié)點(diǎn),位圖置0

可靠信號(hào)的注銷:

刪除信號(hào)的一個(gè)信息節(jié)點(diǎn),當(dāng)前沒有相同節(jié)點(diǎn)則位圖置0

信號(hào)處理

處理就是調(diào)用信號(hào)的處理函數(shù)

有三種處理方式

默認(rèn)處理:系統(tǒng)中已經(jīng)定義好了處理方式

忽略處理:空的處理方式

SIGCHLD:子進(jìn)程再退出時(shí)給父進(jìn)程發(fā)送一個(gè)SIGCHLD信號(hào),父進(jìn)程對(duì)于該信號(hào)的處理方式是忽略處理 該信號(hào)對(duì)于所有進(jìn)程而言都是忽略處理

自定義處理:自己定義一個(gè)處理函數(shù),替換掉處理函數(shù)

自定義處理函數(shù)signal

用handler函數(shù),替換signum信號(hào)當(dāng)前的處理函數(shù)

自定義信號(hào)的捕捉流程(捕捉流程:從用戶態(tài)進(jìn)入內(nèi)核態(tài),找到信號(hào)并處理的過(guò)程)

進(jìn)入內(nèi)核的原因:

  • 系統(tǒng)調(diào)用函數(shù)
  • 中斷
  • 進(jìn)程異常

當(dāng)前執(zhí)行流在用戶態(tài)收到信號(hào),不能立即處理信號(hào),而是從用戶態(tài)切換到內(nèi)核態(tài)時(shí)處理

進(jìn)入內(nèi)核后,執(zhí)行流并不知道要處理信號(hào),而是執(zhí)行一些功能當(dāng)要從內(nèi)核態(tài)返回到用戶態(tài),一定會(huì)調(diào)用do_signal函數(shù)判斷當(dāng)前進(jìn)程有無(wú)收到信號(hào),收到則立即處理,沒有直接返回到用戶態(tài)

如果有信號(hào)就執(zhí)行信號(hào)對(duì)應(yīng)動(dòng)作

如果是自定義處理方式,會(huì)從內(nèi)核態(tài)切換到用戶態(tài)執(zhí)行自定義函數(shù),調(diào)用sigreturn函數(shù)再次進(jìn)入到內(nèi)核(不能以內(nèi)核身份執(zhí)行用戶寫的自定義代碼)

再去調(diào)用dosignal判斷是否有其它信號(hào)需要處理

信號(hào)阻塞

阻塞(阻塞不是在處理信號(hào))

信號(hào)被阻塞后依然會(huì)注冊(cè),但是暫時(shí)不處理(直到被解除阻塞)

PCB中有個(gè)block阻塞信號(hào)集合,哪個(gè)信號(hào)被添加到block阻塞集合中,表示收到信號(hào)但暫時(shí)不處理

更改或獲取進(jìn)程的信號(hào)block表(將信號(hào)集合設(shè)置進(jìn)內(nèi)核)

int sigprocmask(int how, const sigset_t* set, sigset_t* oset)

how:對(duì)PCB中信號(hào)阻塞集合進(jìn)行的操作

SIG_BLOCK:block|=set

把set集合中的信號(hào)添加到block集合中,阻塞set集合中的信號(hào)

SIG_UNBLOCK:block&=~set

解除

SIG_SETMASK:block=set

重新設(shè)置block表

oldset將修改前block集合中的信息添加到old中,便于還原

是輸出型參數(shù),將原block返回,不想返回設(shè)置為NULL

要屏蔽2號(hào)信號(hào),將2號(hào)信號(hào)添加到set中

set是輸入型參數(shù)

  • 函數(shù)在阻塞指定信號(hào)時(shí),就要傳進(jìn)去一個(gè)集合, 意味著要將所有的信號(hào)添加到一個(gè)集合中
  • 所以要先定義一個(gè)信號(hào)集合的變量sigset_t
  • 通過(guò)sigsetempty(sigset* set)先將集合中的數(shù)據(jù)清空
  • 通過(guò)sigaddset(sigset_t* set, int sugnum)----將signum添加到set集合中(單個(gè)添加)
  • 通過(guò)sigfillset(sigset_t *set)------------------------將所有信號(hào)添加到set中
  • 通過(guò)sigdelset(sigset_t *set, int signum)----移除指定信號(hào)
  • 通過(guò)sigismember(sigset_t *set, int signum)–按段信號(hào)signum是(返回1)否(-1)在set信號(hào)集合中

9號(hào)和19號(hào)不能被阻塞,忽略,自定義

僵尸進(jìn)程是已經(jīng)死了的

SIGPIPE

  • 管道讀端關(guān)閉,繼續(xù)寫,會(huì)在write會(huì)觸發(fā)異常

SIGCHLD

  • 子進(jìn)程退出時(shí)給父進(jìn)程發(fā)送的信號(hào)
  • 這個(gè)信號(hào)的默認(rèn)處理方式是忽略,因此未對(duì)子進(jìn)程退出做出處理

修改SIGCHLD的默認(rèn)處理方法(讓回調(diào)函數(shù)內(nèi)部wait子進(jìn)程)其實(shí)并不合理

因?yàn)樵撔盘?hào)是非可靠信號(hào),大量子進(jìn)程同時(shí)退出,發(fā)出的多個(gè)非可靠信號(hào)可能只注冊(cè)了一次

可直接顯示忽略,明確告訴OS,子進(jìn)程退出我不關(guān)心,直接把資源回收

signal(SIGCHLD, SIG_IGN)

或者在回調(diào)函數(shù)內(nèi)部,使用waitpid循環(huán)等待每一個(gè)子進(jìn)程退出的信號(hào)

int sigpending(sigset_t *set)

獲取當(dāng)前進(jìn)程的pending信號(hào)集(輸出型參數(shù)),放入set集合中

PCB如何獲取signal函數(shù)使用自定義信號(hào)

在PCB有一個(gè)結(jié)構(gòu)體指針struct sighand_struct* sighand,該指針指向結(jié)構(gòu)體sighand_struct;

該結(jié)構(gòu)體中有一個(gè)struct k_sigaction action[_NSIG]數(shù)組,數(shù)組中的每個(gè)元素是一個(gè)多重嵌套結(jié)構(gòu)體,如圖

  • action數(shù)組中一個(gè)元素就保存了一個(gè)信號(hào)對(duì)應(yīng)的處理方式,
  • 例如,2號(hào)信號(hào)對(duì)應(yīng)一個(gè)action數(shù)組中的元素,2號(hào)信號(hào)的處理方式就保存在_sighander_t類型的變量中
  • 該類型的變量保存了三種數(shù)據(jù),就是上述的三種信號(hào)處理方式,默認(rèn)處理、忽略處理、自定義處理

PCB與signal函數(shù)的關(guān)系

  • 在調(diào)用signal函數(shù),參數(shù)sighandler保存了新函數(shù)地址,該新地址是傳送給PCB中action數(shù)組的元素,該元素內(nèi)容被修改
  • 就通過(guò)signal函數(shù)改變了2號(hào)信號(hào)的處理方式,
  • 當(dāng)進(jìn)程在處理2號(hào)時(shí)通過(guò)PCB一步步找到action數(shù)組找到2號(hào)信號(hào)的處理方式,發(fā)現(xiàn)其處理方式是自定義的函數(shù)
  • 從而調(diào)用自定義的函數(shù)

sigaction函數(shù)

修改指定信號(hào)的處理動(dòng)作

改變action數(shù)組元素中第二個(gè)結(jié)構(gòu)體,而signal函數(shù)只是改變?cè)摻Y(jié)構(gòu)體下的一個(gè)成員變量

需要配合其他函數(shù)使用

sa_handler是信號(hào)的處理方式

sa_mask:信號(hào)正在被處理時(shí),內(nèi)存會(huì)將當(dāng)前信號(hào)加入到信號(hào)屏蔽字,信號(hào)返回時(shí)回復(fù)成原來(lái)的信號(hào)屏蔽字

這樣保證了在處理某個(gè)信號(hào)時(shí),此信號(hào)再次產(chǎn)生就會(huì)被阻塞直到當(dāng)前處理結(jié)束

需要用到的清空函數(shù)(上圖黑色部分指錯(cuò)了):

可重入函數(shù)

現(xiàn)有一個(gè)鏈表需要進(jìn)行頭插,在執(zhí)行頭插函數(shù)時(shí),代碼進(jìn)入內(nèi)核在退出時(shí)發(fā)現(xiàn)一個(gè)信號(hào),該信號(hào)也是在執(zhí)行頭插代碼

這樣會(huì)發(fā)生內(nèi)存泄漏,信號(hào)所調(diào)用的頭插函數(shù)插入的節(jié)點(diǎn)找不到了,這種函數(shù)就稱為不可重入函數(shù)

如果只是訪問(wèn)變量或者參數(shù),則稱為可重入函數(shù)

volatile關(guān)鍵字

在編譯的時(shí)候,全局變量flags只進(jìn)行邏輯運(yùn)算,編譯器會(huì)自動(dòng)將其優(yōu)化,將變量?jī)?yōu)化到寄存器中

不從內(nèi)存中讀取,而信號(hào)修改flag的值只是對(duì)內(nèi)存值修改

防止編譯時(shí)因優(yōu)化,使CPU不從內(nèi)存中取值,而從寄存器中取值

sigchld

子進(jìn)程退出時(shí)不是默默的退出

子進(jìn)程退出時(shí)會(huì)給父進(jìn)程發(fā)送SIGCHLD信號(hào),該信號(hào)的默認(rèn)處理方式是IGN(忽略)

無(wú)論是阻塞還是非阻塞,都需要父進(jìn)程主動(dòng)去詢問(wèn)

則現(xiàn)在提前告訴子進(jìn)程,子進(jìn)程死亡時(shí)發(fā)消息,父進(jìn)程收到后回收資源即可

所以通過(guò)signal函數(shù)修改SIGCHLD信號(hào)的處理方式,改為wait等待子進(jìn)程即可

前七個(gè)子進(jìn)程結(jié)束,通過(guò)waitpid等待成功,在等待第八個(gè)子進(jìn)程退出時(shí),父進(jìn)程會(huì)阻塞在waitpid函數(shù)處

通過(guò)sigaction將SIGCHLD的處理動(dòng)作設(shè)置為SIG_IGN,這樣fork出來(lái)的子進(jìn)程在終止時(shí)會(huì)自動(dòng)清理掉,不會(huì)產(chǎn)生僵尸進(jìn)程

這兩個(gè)忽略其實(shí)沒有任何區(qū)別

意義:手動(dòng)設(shè)置了SIG_IGN,除了修改父進(jìn)程,子進(jìn)程也會(huì)受影響,讓子進(jìn)程退出不給對(duì)應(yīng)父進(jìn)程發(fā)送信號(hào)

在OS層面上,手動(dòng)設(shè)置信號(hào),會(huì)在設(shè)置子進(jìn)程時(shí)不給父進(jìn)程發(fā)消息,并自動(dòng)釋放

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Ubuntu安裝MySQL5.7并配置數(shù)據(jù)存儲(chǔ)路徑的方法步驟

    Ubuntu安裝MySQL5.7并配置數(shù)據(jù)存儲(chǔ)路徑的方法步驟

    這篇文章主要介紹了Ubuntu安裝MySQL5.7并配置數(shù)據(jù)存儲(chǔ)路徑的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • CentOS8.0 網(wǎng)絡(luò)配置的實(shí)現(xiàn)

    CentOS8.0 網(wǎng)絡(luò)配置的實(shí)現(xiàn)

    這篇文章主要介紹了CentOS8.0 網(wǎng)絡(luò)配置的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Linux系統(tǒng)管理常用命令及參數(shù)說(shuō)明中文版

    Linux系統(tǒng)管理常用命令及參數(shù)說(shuō)明中文版

    這篇文章主要介紹了Linux系統(tǒng)管理常用命令及其參數(shù)的中文版說(shuō)明,方便了英文不好的同學(xué)學(xué)習(xí)Linux,需要的朋友可以參考下
    2014-03-03
  • Ubuntu基礎(chǔ)教程之a(chǎn)pt-get命令

    Ubuntu基礎(chǔ)教程之a(chǎn)pt-get命令

    這篇文章主要給大家介紹了關(guān)于Ubuntu基礎(chǔ)教程之a(chǎn)pt-get命令的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Ubuntu系統(tǒng)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Apache多虛擬主機(jī)多站點(diǎn)配置的兩種實(shí)現(xiàn)方案

    Apache多虛擬主機(jī)多站點(diǎn)配置的兩種實(shí)現(xiàn)方案

    本文介紹了在Apache服務(wù)器上配置多虛擬主機(jī)的兩種方案:基于IP地址的虛擬主機(jī)配置和基于域名的虛擬主機(jī)配置,詳細(xì)說(shuō)明了每個(gè)方案的配置步驟,以實(shí)現(xiàn)在同一臺(tái)服務(wù)器上托管多個(gè)網(wǎng)站的目的,感興趣的可以了解一下
    2024-09-09
  • 如何利用watch幫你重復(fù)執(zhí)行命令

    如何利用watch幫你重復(fù)執(zhí)行命令

    這篇文章主要給大家介紹了關(guān)于如何利用watch幫你重復(fù)執(zhí)行命令的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用linux系統(tǒng)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • Linux關(guān)機(jī)時(shí)執(zhí)行指定腳本功能實(shí)現(xiàn)

    Linux關(guān)機(jī)時(shí)執(zhí)行指定腳本功能實(shí)現(xiàn)

    本篇文章給大家分享了Linux關(guān)機(jī)時(shí)執(zhí)行指定腳本功能的實(shí)現(xiàn)詳解,對(duì)此有需要的朋友跟著小編一起學(xué)習(xí)下。
    2018-03-03
  • linux系統(tǒng)中設(shè)置定時(shí)任務(wù)的實(shí)現(xiàn)方式

    linux系統(tǒng)中設(shè)置定時(shí)任務(wù)的實(shí)現(xiàn)方式

    在SpringBoot中設(shè)置定時(shí)任務(wù),需要使用@EnableScheduling注解和@Scheduled注解,配合cron表達(dá)式,在Linux系統(tǒng)中,使用crontab工具可設(shè)置系統(tǒng)級(jí)的定時(shí)任務(wù),首先需要?jiǎng)?chuàng)建執(zhí)行腳本,并賦予執(zhí)行權(quán)限,然后通過(guò)crontab?-e進(jìn)入編輯界面
    2024-10-10
  • ubuntu安裝顯卡驅(qū)動(dòng)和cuda教程

    ubuntu安裝顯卡驅(qū)動(dòng)和cuda教程

    這篇文章主要介紹了ubuntu安裝顯卡驅(qū)動(dòng)和cuda教程,文中附有詳細(xì)的圖文安裝步驟以及安裝配置代碼,跟著本文來(lái)進(jìn)行操作,有需要的朋友可以參考下
    2021-09-09
  • linux中誤刪除程序包恢復(fù)實(shí)例

    linux中誤刪除程序包恢復(fù)實(shí)例

    Linux 下的文件一旦被刪除,是難以恢復(fù)的。對(duì)于家庭單機(jī)使用的Linux ,或者誤刪文件后及時(shí)補(bǔ)救,還是可以恢復(fù)的。下面就來(lái)介紹一下。
    2016-10-10

最新評(píng)論