• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-4  評(píng)論-40  文章-117  trackbacks-0


            信號(hào)與進(jìn)程是分不開的,而把信號(hào)與進(jìn)程的筆記分開來(lái)寫,是因?yàn)槲矣X得這個(gè)信號(hào)太難搞懂了,特別是APUE信號(hào)這一章還把信號(hào)結(jié)合歷史來(lái)介紹弄的我云里霧里。 

            信號(hào)本質(zhì)上是在軟件層次上對(duì)中斷機(jī)制的一種模擬,他有幾種產(chǎn)生方式和處理方式(APUE有介紹),下面帶著疑惑從幾個(gè)角度對(duì)信號(hào)進(jìn)行介紹 


            (一)    站在進(jìn)程的角度

            進(jìn)程發(fā)現(xiàn)和接受信號(hào)

            我們知道,信號(hào)是異步的,一個(gè)進(jìn)程不可能等待信號(hào)的到來(lái),也不知道信號(hào)會(huì)到來(lái),那么,進(jìn)程是如何發(fā)現(xiàn)和接受信號(hào)呢?實(shí)際上,信號(hào)的接收不是由用戶進(jìn)程來(lái)完成的,而是由內(nèi)核代理。當(dāng)一個(gè)進(jìn)程P2向另一個(gè)進(jìn)程P1發(fā)送信號(hào)后,內(nèi)核接受到信號(hào),并將其放在P1的信號(hào)隊(duì)列當(dāng)中。當(dāng)P1再次陷入內(nèi)核態(tài)時(shí),會(huì)檢查信號(hào)隊(duì)列,并根據(jù)相應(yīng)的信號(hào)調(diào)取相應(yīng)的信號(hào)處理函數(shù)

            Task _struct 是進(jìn)程控制塊(PCB),詳見          http://oss.org.cn/kernel-book/ch04/4.3.htm

             

            信號(hào)檢測(cè)和響應(yīng)時(shí)機(jī)

            剛才我們說(shuō),當(dāng)P1再次陷入內(nèi)核時(shí),會(huì)檢查信號(hào)隊(duì)列。那么,P1什么時(shí)候會(huì)再次陷入內(nèi)核呢?陷入內(nèi)核后在什么時(shí)機(jī)會(huì)檢測(cè)信號(hào)隊(duì)列呢?

            1.      當(dāng)前進(jìn)程由于系統(tǒng)調(diào)用、中斷或異常而進(jìn)入系統(tǒng)空間以后,從系統(tǒng)空間返回到用戶空間的前夕。

            2.      當(dāng)前進(jìn)程在內(nèi)核中進(jìn)入睡眠以后剛被喚醒的時(shí)候(必定是在系統(tǒng)調(diào)用中),或者由于不可忽略信號(hào)的存在而提前返回到用戶空間


            進(jìn)入信號(hào)處理函數(shù)

             

             


            對(duì)于sigprocmask 會(huì)進(jìn)入內(nèi)核空間、pause需要從進(jìn)入睡眠這兩者都符合檢測(cè)處理信號(hào)函數(shù)的條件,所以存在忽略信號(hào)的情況,而APUE講sigsuspend的之后真是晦澀難懂,其實(shí)他主要做的工作就是等待一個(gè)中斷然后執(zhí)行相應(yīng)的handle處理

            所以我感覺例子中的

            sigsuspend(&zeromask);

            sigprocmask(SIG_SETMASK, &oldmask,NULL);

            是不是可以直接替換為

            Sigsuspend(&oldmask)

            因?yàn)闇y(cè)試情況難以出現(xiàn),這里只是個(gè)人理解并未得到驗(yàn)證

             

             

            (二)  站在信號(hào)自身的角度

             

            信號(hào)生命周期:

             對(duì)于一個(gè)完整的信號(hào)生命周期(從信號(hào)發(fā)送到相應(yīng)的處理函數(shù)執(zhí)行完畢)來(lái)說(shuō),可以分為三個(gè)重要的階段,這三個(gè)階段由四個(gè)重要事件來(lái)刻畫:

            1.信號(hào)誕生;

            2.信號(hào)在進(jìn)程中注冊(cè)完畢;

            3.信號(hào)在進(jìn)程中的注銷完畢;

            4.信號(hào)處理函數(shù)執(zhí)行完畢。

            相鄰兩個(gè)事件的時(shí)間間隔構(gòu)成信號(hào)生命周期的一個(gè)階段。

             

                詳細(xì)描述各個(gè)生命周期

            1.     信號(hào)"誕生"。

            信號(hào)的誕生指的是觸發(fā)信號(hào)的事件發(fā)生(如檢測(cè)到硬件異常、定時(shí)器超時(shí)以及調(diào)用信號(hào)發(fā)送函數(shù)kill()或sigqueue()等)。 

            2.      信號(hào)在目標(biāo)進(jìn)程中"注冊(cè)"。

            這里注冊(cè)定義不是由signal或者sigaction實(shí)現(xiàn)的,而是說(shuō)信號(hào)發(fā)生之后內(nèi)核中自動(dòng)對(duì)信號(hào)的注冊(cè)保存。

            進(jìn)程的task_struct結(jié)構(gòu)中有關(guān)于本進(jìn)程中未決信號(hào)的數(shù)據(jù)成員: 

            struct sigpending pending;

            struct sigpending

            {

                struct sigqueue *head, **tail;

                sigset_t signal;

            };

            第一、第二個(gè)成員分別指向一個(gè)sigqueue類型的結(jié)構(gòu)鏈(稱之為"未決信號(hào)信息鏈")的首尾,第三個(gè)成員是進(jìn)程中所有未決信號(hào)集,信息鏈中的每個(gè)sigqueue結(jié)構(gòu)體刻畫一個(gè)特定信號(hào)所攜帶的信息,并指向下一個(gè)sigqueue結(jié)構(gòu):

            struct sigqueue

            {

                struct sigqueue *next;

                siginfo_t info;

            };

                信號(hào)在進(jìn)程中注冊(cè)指的就是信號(hào)值加入到進(jìn)程的未決信號(hào)集中(sigpending結(jié)構(gòu)的第二個(gè)成員sigset_t signal),并且信號(hào)所攜帶的信息被保留到未決信號(hào)信息鏈的某個(gè)sigqueue結(jié)構(gòu)中。只要信號(hào)在進(jìn)程的未決信號(hào)集中,表明進(jìn)程已經(jīng)知道這些信號(hào)的存在,但還沒來(lái)得及處理,或者該信號(hào)被進(jìn)程阻塞。

            注: 

                當(dāng)一個(gè)實(shí)時(shí)信號(hào)發(fā)送給一個(gè)進(jìn)程時(shí),不管該信號(hào)是否已經(jīng)在進(jìn)程中注冊(cè),都會(huì)被再注冊(cè)一次,因此,信號(hào)不會(huì)丟失,因此,實(shí)時(shí)信號(hào)又叫做"可靠信號(hào)"。這意味著同一個(gè)實(shí)時(shí)信號(hào)可以在同一個(gè)進(jìn)程的未決信號(hào)信息鏈中占有多個(gè)sigqueue結(jié)構(gòu)(進(jìn)程每收到一個(gè)實(shí)時(shí)信號(hào),都會(huì)為它分配一個(gè)結(jié)構(gòu)來(lái)登記該信號(hào)信息,并把該結(jié)構(gòu)添加在未決信號(hào)鏈尾,即所有誕生的實(shí)時(shí)信號(hào)都會(huì)在目標(biāo)進(jìn)程中注冊(cè));

            當(dāng)一個(gè)非實(shí)時(shí)信號(hào)發(fā)送給一個(gè)進(jìn)程時(shí),如果該信號(hào)已經(jīng)在進(jìn)程中注冊(cè),則該信號(hào)將被丟棄,造成信號(hào)丟失。因此,非實(shí)時(shí)信號(hào)又叫做"不可靠信號(hào)"。這意味著同一個(gè)非實(shí)時(shí)信號(hào)在進(jìn)程的未決信號(hào)信息鏈中,至多占有一個(gè)sigqueue結(jié)構(gòu)。一個(gè)非實(shí)時(shí)信號(hào)誕生后,(1)、如果發(fā)現(xiàn)相同的信號(hào)已經(jīng)在目標(biāo)結(jié)構(gòu)中注冊(cè),則不再注冊(cè),對(duì)于進(jìn)程來(lái)說(shuō),相當(dāng)于不知道本次信號(hào)發(fā)生,信號(hào)丟失;(2)、如果進(jìn)程的未決信號(hào)中沒有相同信號(hào),則在進(jìn)程中注冊(cè)自己。在APUE的不可靠信號(hào)章節(jié)中需要每次重新聲明sinal_hanle函數(shù),這個(gè)是說(shuō)的以前Unix系統(tǒng)的處理,現(xiàn)在可靠不可靠就是上面所說(shuō)的實(shí)時(shí)與注冊(cè)次數(shù)的區(qū)別。


            3.信號(hào)在進(jìn)程中的注銷。

            在目標(biāo)進(jìn)程執(zhí)行過程中,會(huì)檢測(cè)是否有信號(hào)等待處理(每次從系統(tǒng)空間返回到用戶空間時(shí)都做這樣的檢查)。(“sigprocmask返回前,也至少會(huì)將其中一個(gè)未決且未阻塞的信號(hào)遞送給進(jìn)程”)如果存在未決信號(hào)等待處理且該信號(hào)沒有被進(jìn)程阻塞,則在運(yùn)行相應(yīng)的信號(hào)處理函數(shù)前,進(jìn)程會(huì)把信號(hào)在未決信號(hào)鏈中占有的結(jié)構(gòu)卸掉。是否將信號(hào)從進(jìn)程未決信號(hào)集中刪除對(duì)于實(shí)時(shí)與非實(shí)時(shí)信號(hào)是不同的。對(duì)于非實(shí)時(shí)信號(hào)來(lái)說(shuō),由于在未決信號(hào)信息鏈中最多只占用一個(gè)sigqueue結(jié)構(gòu),因此該結(jié)構(gòu)被釋放后,應(yīng)該把信號(hào)在進(jìn)程未決信號(hào)集中刪除(信號(hào)注銷完畢);而對(duì)于實(shí)時(shí)信號(hào)來(lái)說(shuō),可能在未決信號(hào)信息鏈中占用多個(gè)sigqueue結(jié)構(gòu),因此應(yīng)該針對(duì)占用gqueue結(jié)構(gòu)的數(shù)目區(qū)別對(duì)待:如果只占用一個(gè)sigqueue結(jié)構(gòu)(進(jìn)程只收到該信號(hào)一次),則應(yīng)該把信號(hào)在進(jìn)程的未決信號(hào)集中刪除(信號(hào)注銷完畢)。否則,不在進(jìn)程的未決信號(hào)集中刪除該信號(hào)(信號(hào)注銷完畢)。進(jìn)程在執(zhí)行信號(hào)相應(yīng)處理函數(shù)之前,首先要把信號(hào)在進(jìn)程中注銷。


            4.信號(hào)生命終止。

            進(jìn)程注銷信號(hào)后,立即執(zhí)行相應(yīng)的信號(hào)處理函數(shù),執(zhí)行完畢后,信號(hào)的本次發(fā)送對(duì)進(jìn)程的影響徹底結(jié)束。 


            注: 

            1)信號(hào)注冊(cè)與否,與發(fā)送信號(hào)的函數(shù)(如kill()或sigqueue()等)以及信號(hào)安裝函數(shù)(signal()及sigaction())無(wú)關(guān),只與信號(hào)值有關(guān)(信號(hào)值小于SIGRTMIN的信號(hào)最多只注冊(cè)一次,信號(hào)值在SIGRTMIN及SIGRTMAX之間的信號(hào),只要被進(jìn)程接收到就被注冊(cè))。

            2)在信號(hào)被注銷到相應(yīng)的信號(hào)處理函數(shù)執(zhí)行完畢這段時(shí)間內(nèi),如果進(jìn)程又收到同一信號(hào)多次,則對(duì)實(shí)時(shí)信號(hào)來(lái)說(shuō),每一次都會(huì)在進(jìn)程中注冊(cè);而對(duì)于非實(shí)時(shí)信號(hào)來(lái)說(shuō),無(wú)論收到多少次信號(hào),都會(huì)視為只收到一個(gè)信號(hào),只在進(jìn)程中注冊(cè)一次。

             

            (三)  進(jìn)程和信號(hào)兩者的角度來(lái)看

            實(shí)際執(zhí)行信號(hào)的處理動(dòng)作稱為信號(hào)遞達(dá)(Delivery),信號(hào)從產(chǎn)生到遞達(dá)之間的狀態(tài),稱為信號(hào)未決(Pending)。進(jìn)程可以選擇阻塞(Block)某個(gè)信號(hào)。被阻塞的信號(hào)產(chǎn)生時(shí)將保持在未決狀態(tài),直到進(jìn)程解除對(duì)此信號(hào)的阻塞,才執(zhí)行遞達(dá)的動(dòng)作。注意,阻塞和忽略是不同的,只要信號(hào)被阻塞就不會(huì)遞達(dá),而忽略是在遞達(dá)之后可選的一種處理動(dòng)作。信號(hào)在內(nèi)核中的表示可以看作是這樣的:

            信號(hào)在內(nèi)核中的表示示意圖

             每個(gè)信號(hào)都有兩個(gè)標(biāo)志位分別表示阻塞和未決,還有一個(gè)函數(shù)指針表示處理動(dòng)作。信號(hào)產(chǎn)生時(shí),內(nèi)核在進(jìn)程控制塊中設(shè)置該信號(hào)的未決標(biāo)志,直到信號(hào)遞達(dá)才清除該標(biāo)志。在上圖的例子中,

            1.      SIGHUP信號(hào)未阻塞也未產(chǎn)生過,當(dāng)它遞達(dá)時(shí)執(zhí)行默認(rèn)處理動(dòng)作。

            2.      SIGINT信號(hào)產(chǎn)生過,但正在被阻塞,所以暫時(shí)不能遞達(dá)。雖然它的處理動(dòng)作是忽略,但在沒有解除阻塞之前不能忽略這個(gè)信號(hào),因?yàn)檫M(jìn)程仍有機(jī)會(huì)改變處理動(dòng)作之后再解除阻塞。

            3.      SIGQUIT信號(hào)未產(chǎn)生過,一旦產(chǎn)生SIGQUIT信號(hào)將被阻塞,它的處理動(dòng)作是用戶自定義函數(shù)sighandler。

             


            posted on 2012-02-10 17:49 李陽(yáng) 閱讀(652) 評(píng)論(1)  編輯 收藏 引用 所屬分類: Linux

            評(píng)論:
            # re: Linux 信號(hào) (轉(zhuǎn)) 2013-05-19 10:18 | cjg
            好文,清晰。  回復(fù)  更多評(píng)論
              
            国产精品成人久久久久久久| 热久久国产欧美一区二区精品 | 最新久久免费视频| 国产亚洲精久久久久久无码77777| 麻豆成人久久精品二区三区免费 | 中文字幕一区二区三区久久网站| 久久久久亚洲AV成人网人人软件| 一本色道久久HEZYO无码| 国内精品伊人久久久久| 四虎影视久久久免费| MM131亚洲国产美女久久| 亚洲国产精品成人久久蜜臀| 久久免费精品一区二区| 久久久无码精品亚洲日韩京东传媒 | 久久伊人精品一区二区三区| 精品国产热久久久福利| 国产精品对白刺激久久久| 久久久国产一区二区三区| 国产精品久久久久AV福利动漫 | 精品国际久久久久999波多野| 亚洲va久久久久| 久久久噜噜噜久久| 91精品国产综合久久香蕉 | 色综合久久天天综合| 亚洲中文精品久久久久久不卡| 色偷偷91久久综合噜噜噜噜 | 久久精品无码午夜福利理论片 | 中文精品久久久久人妻不卡| 日本高清无卡码一区二区久久| 国产成人久久久精品二区三区| 久久综合久久综合久久| 国产精品久久久久影院嫩草| 亚洲欧美日韩中文久久| 亚洲中文字幕久久精品无码喷水| 久久婷婷人人澡人人爽人人爱| 香蕉久久永久视频| 一本大道久久香蕉成人网| 亚洲欧美国产精品专区久久 | 欧美日韩中文字幕久久伊人| 成人综合伊人五月婷久久| 97久久久久人妻精品专区|