亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Linux中的信號(注冊,注銷,處理,阻塞)

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

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

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

信號注冊

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

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

非可靠信號注冊:

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

可靠信號注冊:

  • 不管位圖是否置1(是否已經(jīng)注冊,還沒處理),都會添加一個信號節(jié)點

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

信號注銷

什么是注銷:

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

非可靠信號的注銷:

刪除信號的信息節(jié)點,位圖置0

可靠信號的注銷:

刪除信號的一個信息節(jié)點,當前沒有相同節(jié)點則位圖置0

信號處理

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

有三種處理方式

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

忽略處理:空的處理方式

SIGCHLD:子進程再退出時給父進程發(fā)送一個SIGCHLD信號,父進程對于該信號的處理方式是忽略處理 該信號對于所有進程而言都是忽略處理

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

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

用handler函數(shù),替換signum信號當前的處理函數(shù)

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

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

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

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

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

如果有信號就執(zhí)行信號對應(yīng)動作

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

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

信號阻塞

阻塞(阻塞不是在處理信號)

信號被阻塞后依然會注冊,但是暫時不處理(直到被解除阻塞)

PCB中有個block阻塞信號集合,哪個信號被添加到block阻塞集合中,表示收到信號但暫時不處理

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

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

how:對PCB中信號阻塞集合進行的操作

SIG_BLOCK:block|=set

把set集合中的信號添加到block集合中,阻塞set集合中的信號

SIG_UNBLOCK:block&=~set

解除

SIG_SETMASK:block=set

重新設(shè)置block表

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

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

要屏蔽2號信號,將2號信號添加到set中

set是輸入型參數(shù)

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

9號和19號不能被阻塞,忽略,自定義

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

SIGPIPE

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

SIGCHLD

  • 子進程退出時給父進程發(fā)送的信號
  • 這個信號的默認處理方式是忽略,因此未對子進程退出做出處理

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

因為該信號是非可靠信號,大量子進程同時退出,發(fā)出的多個非可靠信號可能只注冊了一次

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

signal(SIGCHLD, SIG_IGN)

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

int sigpending(sigset_t *set)

獲取當前進程的pending信號集(輸出型參數(shù)),放入set集合中

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

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

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

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

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

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

sigaction函數(shù)

修改指定信號的處理動作

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

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

sa_handler是信號的處理方式

sa_mask:信號正在被處理時,內(nèi)存會將當前信號加入到信號屏蔽字,信號返回時回復(fù)成原來的信號屏蔽字

這樣保證了在處理某個信號時,此信號再次產(chǎn)生就會被阻塞直到當前處理結(jié)束

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

可重入函數(shù)

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

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

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

volatile關(guān)鍵字

在編譯的時候,全局變量flags只進行邏輯運算,編譯器會自動將其優(yōu)化,將變量優(yōu)化到寄存器中

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

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

sigchld

子進程退出時不是默默的退出

子進程退出時會給父進程發(fā)送SIGCHLD信號,該信號的默認處理方式是IGN(忽略)

無論是阻塞還是非阻塞,都需要父進程主動去詢問

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

所以通過signal函數(shù)修改SIGCHLD信號的處理方式,改為wait等待子進程即可

前七個子進程結(jié)束,通過waitpid等待成功,在等待第八個子進程退出時,父進程會阻塞在waitpid函數(shù)處

通過sigaction將SIGCHLD的處理動作設(shè)置為SIG_IGN,這樣fork出來的子進程在終止時會自動清理掉,不會產(chǎn)生僵尸進程

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

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

在OS層面上,手動設(shè)置信號,會在設(shè)置子進程時不給父進程發(fā)消息,并自動釋放

總結(jié)

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

相關(guān)文章

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

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

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

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

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

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

    這篇文章主要介紹了Linux系統(tǒng)管理常用命令及其參數(shù)的中文版說明,方便了英文不好的同學學習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)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Ubuntu系統(tǒng)具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-08-08
  • Apache多虛擬主機多站點配置的兩種實現(xiàn)方案

    Apache多虛擬主機多站點配置的兩種實現(xiàn)方案

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

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

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

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

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

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

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

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

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

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

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

最新評論