在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁 > 博客 > Linux信號(hào)(signal)機(jī)制

            Linux信號(hào)(signal)機(jī)制

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

            信號(hào)(signal)是一種軟中斷,信號(hào)機(jī)制是進(jìn)程間通信的一種方式,采用異步通信方式

            一、信號(hào)類型

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

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

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

            1.2 信號(hào)表

            在終端,可通過kill -l查看所有的signal信號(hào)

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

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

            二、信號(hào)產(chǎn)生

            信號(hào)來源分為硬件類和軟件類:

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

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

            2.2 軟件方式

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

            • kernel,使用 kill_proc_info()等

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

            • java,使用 Procees.sendSignal()等

            三、信號(hào)注冊和注銷3.1 注冊

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

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

            • 實(shí)時(shí)信號(hào)發(fā)送給進(jìn)程時(shí),不管該信號(hào)是否在進(jìn)程中注冊過,都會(huì)再次注冊。故信號(hào)不會(huì)丟失;

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

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

            四、信號(hào)處理

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

            4.1 處理時(shí)機(jī)

            signal信號(hào)處理時(shí)機(jī): 內(nèi)核態(tài) -> signal信號(hào)處理 -> 用戶態(tài):

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

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

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

            4.2 處理方式

            進(jìn)程對(duì)信號(hào)的處理方式: 有3種

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

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

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

            4.3 信號(hào)安裝

            進(jìn)程處理某個(gè)信號(hào)前,需要先在進(jìn)程中安裝此信號(hào)。安裝過程主要是建立信號(hào)值和進(jìn)程對(duì)相應(yīng)信息值的動(dòng)作。

            信號(hào)安裝函數(shù)

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

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

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

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

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

            • sa_flags:標(biāo)示位

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

              • SA_NOCLDSTOP:使父進(jìn)程在它的子進(jìn)程暫?;蚶^續(xù)運(yùn)行時(shí)不會(huì)收到 SIGCHLD 信號(hào)。

              • SA_NOCLDWAIT:使父進(jìn)程在它的子進(jìn)程退出時(shí)不會(huì)收到SIGCHLD信號(hào),這時(shí)子進(jìn)程如果退出也不會(huì)成為僵 尸進(jìn)程。

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

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

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

            函數(shù)原型:

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

            • signum:要操作的signal信號(hào)。

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

            • oldact:原來對(duì)信號(hào)的處理方式。

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

            4.4 信號(hào)發(fā)送
            • kill():用于向進(jìn)程或進(jìn)程組發(fā)送信號(hào);

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

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

            • setitimer():設(shè)置定時(shí)器,計(jì)時(shí)達(dá)到后給進(jìn)程發(fā)送SIGALRM信號(hào),功能比alarm更強(qiáng)大;

            • abort():向進(jìn)程發(fā)送SIGABORT信號(hào),默認(rèn)進(jìn)程會(huì)異常退出。

            • raise():用于向進(jìn)程自身發(fā)送信號(hào);

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

            信號(hào)集操作函數(shù)

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

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

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

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

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

            信號(hào)阻塞函數(shù)

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

              • SIG_BLOCK:將set指向信號(hào)集中的信號(hào),添加到進(jìn)程阻塞信號(hào)集;

              • SIG_UNBLOCK:將set指向信號(hào)集中的信號(hào),從進(jìn)程阻塞信號(hào)集刪除;

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

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

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

            Linux信號(hào)(signal)機(jī)制 - JackPeng博客 (yuanfentiank789.github.io)

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



            關(guān)鍵詞: linux

            相關(guān)推薦

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

            關(guān)閉