中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. "); //-->

        博客專欄

        EEPW首頁 > 博客 > Linux信號(signal)機制

        Linux信號(signal)機制

        發(fā)布人:電子禪石 時間:2021-06-18 來源:工程師 發(fā)布文章

        信號(signal)是一種軟中斷,信號機制是進程間通信的一種方式,采用異步通信方式

        一、信號類型

        Linux系統(tǒng)共定義了64種信號,分為兩大類:可靠信號與不可靠信號,前32種信號為不可靠信號,后32種為可靠信號。

        1.1 概念
        • 不可靠信號: 也稱為非實時信號,不支持排隊,信號可能會丟失, 比如發(fā)送多次相同的信號, 進程只能收到一次. 信號值取值區(qū)間為1~31;

        • 可靠信號: 也稱為實時信號,支持排隊, 信號不會丟失, 發(fā)多少次, 就可以收到多少次. 信號值取值區(qū)間為32~64

        1.2 信號表

        在終端,可通過kill -l查看所有的signal信號

        取值名稱解釋默認動作
        1SIGHUP掛起
        2SIGINT中斷
        3SIGQUIT退出
        4SIGILL非法指令
        5SIGTRAP斷點或陷阱指令
        6SIGABRTabort發(fā)出的信號
        7SIGBUS非法內(nèi)存訪問
        8SIGFPE浮點異常
        9SIGKILLkill信號不能被忽略、處理和阻塞
        10SIGUSR1用戶信號1
        11SIGSEGV無效內(nèi)存訪問
        12SIGUSR2用戶信號2
        13SIGPIPE管道破損,沒有讀端的管道寫數(shù)據(jù)
        14SIGALRMalarm發(fā)出的信號
        15SIGTERM終止信號
        16SIGSTKFLT棧溢出
        17SIGCHLD子進程退出默認忽略
        18SIGCONT進程繼續(xù)
        19SIGSTOP進程停止不能被忽略、處理和阻塞
        20SIGTSTP進程停止
        21SIGTTIN進程停止,后臺進程從終端讀數(shù)據(jù)時
        22SIGTTOU進程停止,后臺進程想終端寫數(shù)據(jù)時
        23SIGURGI/O有緊急數(shù)據(jù)到達當(dāng)前進程默認忽略
        24SIGXCPU進程的CPU時間片到期
        25SIGXFSZ文件大小的超出上限
        26SIGVTALRM虛擬時鐘超時
        27SIGPROFprofile時鐘超時
        28SIGWINCH窗口大小改變默認忽略
        29SIGIOI/O相關(guān)
        30SIGPWR關(guān)機默認忽略
        31SIGSYS系統(tǒng)調(diào)用異常

        對于signal信號,絕大部分的默認處理都是終止進程或停止進程,或dump內(nèi)核映像轉(zhuǎn)儲。 上述的31的信號為非實時信號,其他的信號32-64 都是實時信號。

        二、信號產(chǎn)生

        信號來源分為硬件類和軟件類:

        2.1 硬件方式
        • 用戶輸入:比如在終端上按下組合鍵ctrl+C,產(chǎn)生SIGINT信號;

        • 硬件異常:CPU檢測到內(nèi)存非法訪問等異常,通知內(nèi)核生成相應(yīng)信號,并發(fā)送給發(fā)生事件的進程;

        2.2 軟件方式

        通過系統(tǒng)調(diào)用,發(fā)送signal信號:kill(),raise(),sigqueue(),alarm(),setitimer(),abort()

        • kernel,使用 kill_proc_info()等

        • native,使用 kill() 或者raise()等

        • java,使用 Procees.sendSignal()等

        三、信號注冊和注銷3.1 注冊

        在進程task_struct結(jié)構(gòu)體中有一個未決信號的成員變量 struct sigpending pending。每個信號在進程中注冊都會把信號值加入到進程的未決信號集。

        • 非實時信號發(fā)送給進程時,如果該信息已經(jīng)在進程中注冊過,不會再次注冊,故信號會丟失;

        • 實時信號發(fā)送給進程時,不管該信號是否在進程中注冊過,都會再次注冊。故信號不會丟失;

        3.2 注銷
        • 非實時信號:不可重復(fù)注冊,最多只有一個sigqueue結(jié)構(gòu);當(dāng)該結(jié)構(gòu)被釋放后,把該信號從進程未決信號集中刪除,則信號注銷完畢;

        • 實時信號:可重復(fù)注冊,可能存在多個sigqueue結(jié)構(gòu);當(dāng)該信號的所有sigqueue處理完畢后,把該信號從進程未決信號集中刪除,則信號注銷完畢;

        四、信號處理

        內(nèi)核處理進程收到的signal是在當(dāng)前進程的上下文,故進程必須是Running狀態(tài)。當(dāng)進程喚醒或者調(diào)度后獲取CPU,則會從內(nèi)核態(tài)轉(zhuǎn)到用戶態(tài)時檢測是否有signal等待處理,處理完,進程會把相應(yīng)的未決信號從鏈表中去掉。

        4.1 處理時機

        signal信號處理時機: 內(nèi)核態(tài) -> signal信號處理 -> 用戶態(tài):

        • 在內(nèi)核態(tài),signal信號不起作用;

        • 在用戶態(tài),signal所有未被屏蔽的信號都處理完畢;

        • 當(dāng)屏蔽信號,取消屏蔽時,會在下一次內(nèi)核轉(zhuǎn)用戶態(tài)的過程中執(zhí)行;

        4.2 處理方式

        進程對信號的處理方式: 有3種

        • 默認 接收到信號后按默認的行為處理該信號。 這是多數(shù)應(yīng)用采取的處理方式。

        • 自定義 用自定義的信號處理函數(shù)來執(zhí)行特定的動作

        • 忽略 接收到信號后不做任何反應(yīng)。

        4.3 信號安裝

        進程處理某個信號前,需要先在進程中安裝此信號。安裝過程主要是建立信號值和進程對相應(yīng)信息值的動作。

        信號安裝函數(shù)

        • signal():不支持信號傳遞信息,主要用于非實時信號安裝;

        • sigaction():支持信號傳遞信息,可用于所有信號安裝;

        其中 sigaction結(jié)構(gòu)體

        • sa_handler:信號處理函數(shù)

        • sa_mask:指定信號處理程序執(zhí)行過程中需要阻塞的信號;

        • sa_flags:標(biāo)示位

          • SA_RESTART:使被信號打斷的syscall重新發(fā)起。

          • SA_NOCLDSTOP:使父進程在它的子進程暫?;蚶^續(xù)運行時不會收到 SIGCHLD 信號。

          • SA_NOCLDWAIT:使父進程在它的子進程退出時不會收到SIGCHLD信號,這時子進程如果退出也不會成為僵 尸進程。

          • SA_NODEFER:使對信號的屏蔽無效,即在信號處理函數(shù)執(zhí)行期間仍能發(fā)出這個信號。

          • SA_RESETHAND:信號處理之后重新設(shè)置為默認的處理方式。

          • SA_SIGINFO:使用sa_sigaction成員而不是sa_handler作為信號處理函數(shù)。

        函數(shù)原型:

        int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

        • signum:要操作的signal信號。

        • act:設(shè)置對signal信號的新處理方式。

        • oldact:原來對信號的處理方式。

        • 返回值:0 表示成功,-1 表示有錯誤發(fā)生。

        4.4 信號發(fā)送
        • kill():用于向進程或進程組發(fā)送信號;

        • sigqueue():只能向一個進程發(fā)送信號,不能像進程組發(fā)送信號;主要針對實時信號提出,與sigaction()組合使用,當(dāng)然也支持非實時信號的發(fā)送;

        • alarm():用于調(diào)用進程指定時間后發(fā)出SIGALARM信號;

        • setitimer():設(shè)置定時器,計時達到后給進程發(fā)送SIGALRM信號,功能比alarm更強大;

        • abort():向進程發(fā)送SIGABORT信號,默認進程會異常退出。

        • raise():用于向進程自身發(fā)送信號;

        4.5 信號相關(guān)函數(shù)

        信號集操作函數(shù)

        • sigemptyset(sigset_t *set):信號集全部清0;

        • sigfillset(sigset_t *set): 信號集全部置1,則信號集包含linux支持的64種信號;

        • sigaddset(sigset_t *set, int signum):向信號集中加入signum信號;

        • sigdelset(sigset_t *set, int signum):向信號集中刪除signum信號;

        • sigismember(const sigset_t *set, int signum):判定信號signum是否存在信號集中。

        信號阻塞函數(shù)

        • sigprocmask(int how, const sigset_t *set, sigset_t *oldset)); 不同how參數(shù),實現(xiàn)不同功能

          • SIG_BLOCK:將set指向信號集中的信號,添加到進程阻塞信號集;

          • SIG_UNBLOCK:將set指向信號集中的信號,從進程阻塞信號集刪除;

          • SIG_SETMASK:將set指向信號集中的信號,設(shè)置成進程阻塞信號集;

        • sigpending(sigset_t *set)):獲取已發(fā)送到進程,卻被阻塞的所有信號;

        • sigsuspend(const sigset_t *mask)):用mask代替進程的原有掩碼,并暫停進程執(zhí)行,直到收到信號再恢復(fù)原有掩碼并繼續(xù)執(zhí)行進程。

        Linux信號(signal)機制 - JackPeng博客 (yuanfentiank789.github.io)

        *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



        關(guān)鍵詞: linux

        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉