c++上下文使用訊號小結

來源:互聯網
上載者:User

說明:本文的上下文環境是 unix/linux作業系統,g++編譯環境, gdb調試環境。

signal是 阻塞模式的良好搭擋。一些需要低速調用的程式,例如 socket、oracle串連,若工作在非阻塞模式下,輪詢會有大量的CPU開銷,而阻塞模式則使得程式不能及時處理那些需要即時響應的操作。signal可以將程式從阻塞狀態喚醒,以處理緊急事件,然後再做別的事情。

unix_program_advance 一書中第十章,詳細地介紹了 unix 系統提供的訊號捕獲函數。

在開發中應注意:

1、確定要使用阻塞還是非阻塞。oci和 socket中,預設都是阻塞的。

在socket 中,可以使用  fcntl()來設定O_NONBLOCK, O_NDELAY.


 

if (fcntl(fd, F_SETFL, orig_flags | O_NONBLOCK) < 0) 
{
    
}

在oci中,可以使用 OCIAttrSet()函數的 OCI_ATTR_NONBLOCKING_MODE 屬性值來設定oci的操作為非阻塞模式。詳細的用法見 Oracle Call Interface Programmer's Guide  B10779-01. chapter 2 中 Nonblocking Mode in OCI 一節。

當socket為阻塞模式時,可以使用 setsockopt來設定 recv的逾時時間。

1、任何一個可能無限阻塞的調用,調用之間加一個alarm()

在oracle中,如果在呼叫 oracle時網路掉線。則函數會永遠阻塞。所以,有必要在可能阻塞的函數前,加一個alarm()以在逾時後將其喚醒。

下面樣本了訊號的使用。當函數調用超過3秒後,跳出函數並重新串連資料庫以執行此操作。直到操作三次仍不能成功,則放棄操作。

 

do
{
    alarm(3);
    if(  table.query() == false && errno == EINTR ) 
    {
        conndb();
    }
    else
    {
     break;
    }
}while (retryTimes < 3)

alarm(0);

 

2、用 sigaction() 而不是 signal() 來設定訊號鉤子。signal()跨平台效能不好。在 linux下跑得很健壯的程式,到了 hp-unix或 ibm-aix上表現得非常糟糕,而 solaris上 signal 又有不同的表現。較於 signal, sigaction 定義了被中斷的低速調用是否重新喚起 ( 預設不喚起);sigactionl() 還有屏蔽功能,這使得訊號處理函數可以專註地處理當前的訊號。

 

3、當前訊號處理函數結束前要喚起先前定義的訊號處理函數。

sigaction( signo, NULL, oldHandle );

4、可以設定捕獲所有的訊號,以避免程式收到訊號時意外退出。訊號編號下界限為1,最高界限是SIGMAX,可以使用for()迴圈設定鉤子。

5、子進程會繼承父進程的訊號鉤子,但不能繼承父進程中已經設定的訊號(例如,鬧鐘訊號)。

6、如果想在收到訊號後跳出當前的上下文環境,用  throw()。

 

相關資料 :

1、 <the design of the unix operationg system>第 7.2 訊號  從作業系統實現的角度,詳細地介紹了訊號的分類、訊號如何被喚醒、訊號在什麼情況下會丟失或引發意外。(注 : 書中討論的內容是 原始版本的 signal(),實際上, sigaction 已經解決了訊號丟失、訊號異常的問題。)

2、<Advanced Programming in the UNIX Environment>  第 10章詳細介紹了不可靠訊號signal、可靠訊號sigaction在 posix.1、SVR4、4.3+BSD中,訊號的實現。並給出了對訊號進行處理的相關源碼。

 

 

使用訊號的完整樣本:

 

訊號一個極有用的使用是:將進程從阻塞狀態喚醒。
訊號有一定的局限性。訊號不能像 message 那樣傳遞訊息結構,而只能傳遞一個簡單的訊號。
訊號會破壞程式的流程。因為我們不知道訊號究竟什麼時候會發生。
一個比較合理的處理辦法是:
當進程收到關注的訊號時,執拋出一個異常。這樣,程式可以根據自己的意願想停就停,想開就開。
樣本如下:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.