linux系統編程之訊號(六) 競態條件與sigsuspend函數

來源:互聯網
上載者:User

一、利用pause和alarm函數實現sleep函數

#include <unistd.h>

int pause(void);

pause函數使調用進程掛起直到有訊號遞達。如果訊號的處理動作是終止進程,則進程終止,pause函數沒有機會返回;如果訊號的處理動作是忽略,則進程繼續處於掛起狀態,pause不返回;如果訊號的處理動作是捕捉,則調用了訊號處理函數之後pause返回-1,errno設定為EINTR,所以pause只有出錯的傳回值。錯誤碼EINTR表示“被訊號中斷”。

alarm函數可以參考這裡:http://blog.csdn.net/simba888888/article/details/8944647

下面使用pause和alarm實現sleep(3)函數,稱為mysleep:

#include<stdio.h>#include<signal.h>#include<unistd.h>    void sig_alrm(int signo){    /* nothing to do */}        unsigned int mysleep(unsigned int nsecs){    struct sigaction newact, oldact;    unsigned int unslept;        newact.sa_handler = sig_alrm;    sigemptyset(&newact.sa_mask);    newact.sa_flags = 0;    sigaction(SIGALRM, &newact, &oldact);        alarm(nsecs);    pause();        unslept = alarm(0);    sigaction(SIGALRM, &oldact, NULL);        return unslept;}    int main(void){    while (1)    {        mysleep(2);        printf("Two seconds passed\n");    }    return 0;}

1. main函數調用mysleep函數,後者調用sigaction註冊了SIGALRM訊號的處理函數sig_alrm。

2. 調用alarm(nsecs)設定鬧鐘。

3. 調用pause等待,核心切換到別的進程運行。

4. nsecs秒之後,鬧鐘逾時,核心發SIGALRM給這個進程。

5. 從核心態返回這個進程的使用者態之前處理未決訊號,發現有SIGALRM訊號,其處理函數是sig_alrm。

6. 切換到使用者態執行sig_alrm函數,進入sig_alrm函數時SIGALRM訊號被自動屏蔽,從sig_alrm函數返回時SIGALRM訊號自動解除屏蔽。然後自動執行系統調用sigreturn再次進入核心,再返回使用者態繼續執行進程的主控制流程程(main函數調用的mysleep函數)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.