• <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>

            Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

            路漫漫,長修遠,我們不能沒有錢
            隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
            數(shù)據(jù)加載中……

            防止信號處理失靈(轉(zhuǎn)載)

            ?  防止信號處理失靈
              
               作者:Danny Kalev
               編譯:MTT 工作室
              
               原文出處:Preventing Glitches in Signal Processing
              
              
               摘要:本文將剖析 ANSI <signal.h>庫并示范如何使用其接口。進而討論
               POSIX 信號處理 API。
              
              
               信號處理類似硬件中斷。它們促使某個進程從當前的執(zhí)行控制流程中跳出,以實現(xiàn)特定的行為,待特定處理完成后,再恢復到中斷點繼續(xù)執(zhí)行。本文將剖析
               ANSI <signal.h>庫并示范如何使用其接口。然后,本文將進而討論
               POSIX 信號處理 API。默認情況下,某些信號導致進程終止。例如,試圖存取進程不擁有的內(nèi)存將觸發(fā) SIGSEGV
               (“段故障”)信號,這時該信號會終止進程的執(zhí)行。許多應(yīng)用程序都有這個問題,這是我們不希望看到的。調(diào)試,仿真和事務(wù)處理系統(tǒng)必須處理這樣的信號以便讓進程繼續(xù)執(zhí)行。那么我們?nèi)绾畏乐惯@種發(fā)生呢?
               答案是安裝一個處理器處理進來的信號并在發(fā)生時捕獲它們
              
               第一步:建立信號處理器
              
               信號是內(nèi)核傳給某個進程的一個整數(shù)。當進程接收到信號,它便以以下方式之一響應(yīng):
               忽略該信號;
               讓內(nèi)核完成與該信號關(guān)聯(lián)的默認操作
               捕獲該信號,即讓內(nèi)核將控制傳給信號處理例程,等信號處理例程執(zhí)行完畢,然后又從中斷的地方恢復程序的執(zhí)行。
              
              
               所謂信號處理例程是一個函數(shù),當某個信號發(fā)生時,內(nèi)核會自動調(diào)用該函數(shù)。signal()函數(shù)為給定的信號注冊一個處理例程:typedef void (*handler)(void);
              void * signal(int signum, handler);
               第一個參數(shù)是信號編碼。第二個參數(shù)用戶定義的函數(shù)地址,當信號 signum 產(chǎn)生時,handler 所指向的函數(shù)被調(diào)用。
               除了函數(shù)地址之外,第二個參數(shù)也可以是兩個特殊的值:SIG_IGN 和 SIG_DFL。SIG_IGN 表示該信號應(yīng)被忽略(注意:SIGKILL
               和 SIGSTOP 在無論如何都是不能被阻塞、捕獲或忽略的);SIG_DFL 指示內(nèi)核該信號產(chǎn)生時完成默認行為。
              
               第二步:發(fā)信號
              
               向某個進程發(fā)信號有三種方式:
               進程通過條用 raise() 顯式地發(fā)送信號給自己;
               信號從另一個進程發(fā)送,比方說通過
               kill() 系統(tǒng)調(diào)用或者
               Perl 腳本
               信號從內(nèi)核發(fā)送。例如,當進程試圖存取不屬于自己的內(nèi)存,或在系統(tǒng)關(guān)閉期間存取內(nèi)存時;
              
               第三步:產(chǎn)生和處理信號
              
               下面程序注冊 SIGTERM 處理器。然后產(chǎn)生一個 SIGTERM 信號,從而導致該處理器運行:
               #include <csignal>
              #include <iostream>
              using namespace std;
              void term(int sig)
              {
              ? //..necessary cleanup operations before terminating
              ? cout << "handling signal no." <<sig <<endl;
              }
              int main()
              {
               signal(SIGTERM, term); // register a SIGTERM handler
               raise(SIGTERM); // will cause term() to run
              }
               ANSI <signal.h> 的局限
               當進入就緒狀態(tài)的某個進程準備運行一個 SIGx 信號處理例程時又接收到另一個 SIGx
               信號,這時會發(fā)生什么情況呢?一個方法是讓內(nèi)核中斷該進程并再次運行該信號處理例程。為此,這個處理例程必須是可重入的(re-entrant)。但是,設(shè)計可重入的處理例程決非易事。ANSI
               C 解決重現(xiàn)信號(recurring signals)問題的方法是在執(zhí)行用戶定義的處理例程前,將處理例程重置為 STG_DFL。這樣做是有問題的。
               當兩個信號快速產(chǎn)生時,內(nèi)核運行第一個信號的處理例程,而對第二個信號則進行默認處理,這樣有可能終止該進程。
               在過去的三十年中出現(xiàn)了幾個可以信號處理框架,每一種框架對重現(xiàn)信號的處理問題提供了不同的解決方法。POSIX 信號 API
               是其中最為成熟的和可移植的一個。
              
               POSIX 信號
               POSIX 信號處理函數(shù)操作一組打包在 sigset_t 數(shù)據(jù)類型中信號:
               int sigemptyset(sigset_t * pset); 清除 pset 中的所有信號。
               int sigfillset(sigset_t * pset); 用可獲得的信號填充 pset。
               int sigaddset(sigset_t * pset, int signum); 將 signum 添加到 pset。
               int sigdelset(sigset_t * pset, int signum); 從 pset 中刪除 signum。
               int sigismember(const sigset_t * pset, int signum); 如果 signum 包含在
               pset 中,則返回非零,否則返回 0。
              
               Sigaction() 為特定的信號注冊處理例程:
               int sigaction(int signum, struct sigaction * act, struct sigaction *prev);
               sigaction 結(jié)構(gòu)描述內(nèi)核處理 signum 的信息:struct sigaction
              {
              ? sighanlder_t sa_hanlder;
              ? sigset_t sa_mask; // 阻塞信號的清單
              ? unsigned long sa_flags; // 阻塞模式
              ? void (*sa_restorer)(void); // 未使用
              };
               sa_hanlder 保存函數(shù)的地址,該函數(shù)帶一個整型參數(shù),沒有返回值。它還可以是兩個特別值之一:SIG_DFL 和 SIG_IGN。
              
               額外特性
               POSIX API 提供多種 ANSI 庫中所沒有的服務(wù)。其中包括阻塞進入的信號并獲取當前未決信號。
              
              
               阻塞信號
               sigprocmask() 阻塞和取消阻塞信號:int sigprocmask(int mode, const sigset_t* newmask,sigset_t * oldmask);
               mode 可取以下值之一:
               SIG_BLOCK —— 將 newmask 中的信號添加到當前的信號擋板中。
               SIG_UNBLOCK —— 從當前的信號擋板中刪除 newmask 信號。
               SIG_SETMASK —— 僅阻塞 newmask 中的信號。
               獲取未決信號
               阻塞的信號處于等待狀態(tài),直到進程就緒接收它們。這樣的信號被稱為未決信號,可以通過調(diào)用 sigpending() 來獲取。
               int sigpending(sigset_t * pset);
              
            作者簡介
               Danny Kalev 是一名通過認證的系統(tǒng)分析師,專攻 C++ 和形式語言理論的軟件工程師。1997 年到 2000
               年期間,他是 C++ 標準委員會成員。最近他以優(yōu)異成績完成了他在普通語言學研究方面的碩士論文。
               業(yè)余時間他喜歡聽古典音樂,閱讀維多利亞時期的文學作品,研究 Hittite、Basque 和 Irish Gaelic
               這樣的自然語言。其它興趣包括考古和地理。Danny 時常到一些 C++ 論壇并定期為不同的 C++
               網(wǎng)站和雜志撰寫文章。他還在教育機構(gòu)講授程序設(shè)計語言和應(yīng)用語言課程。

            posted on 2006-09-28 09:55 Khan 閱讀(1227) 評論(0)  編輯 收藏 引用 所屬分類: GCC/G++跨平臺開發(fā)

            久久成人国产精品二三区| 久久九九久精品国产免费直播| 无码伊人66久久大杳蕉网站谷歌| 一级A毛片免费观看久久精品| 亚洲欧美另类日本久久国产真实乱对白| 久久人人爽人人爽AV片| 亚洲色婷婷综合久久| 国产精品一久久香蕉国产线看| 久久亚洲精品视频| 欧美亚洲国产精品久久| 久久婷婷久久一区二区三区| 国产精品一区二区久久精品无码 | 久久这里只精品国产99热| 久久精品中文字幕有码| 久久久久亚洲AV成人片| 久久久久亚洲AV无码专区桃色| 人妻久久久一区二区三区| 精品一久久香蕉国产线看播放| 麻豆成人久久精品二区三区免费| 国产成人久久777777| 久久久无码一区二区三区 | 久久水蜜桃亚洲av无码精品麻豆| 99久久伊人精品综合观看| 亚洲精品国产美女久久久| 亚洲精品美女久久久久99小说| 久久亚洲高清观看| 久久99精品久久久久久hb无码| 久久这里有精品| 亚洲国产高清精品线久久| 韩国三级中文字幕hd久久精品| 久久久无码精品亚洲日韩按摩| 伊人久久五月天| 亚洲精品NV久久久久久久久久| 99久久精品国产一区二区| 国产精品久久久久9999| 久久不见久久见免费视频7| 午夜不卡久久精品无码免费| 一本色道久久99一综合| 午夜欧美精品久久久久久久| 久久精品国产亚洲av麻豆蜜芽| 久久人人爽人人爽人人av东京热 |