国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統 > 正文

信號之sigsetjmp和siglongjmp函數

2024-06-28 13:28:27
字體:
來源:轉載
供稿:網友
信號之sigsetjmp和siglongjmp函數

在信號處理程序中經常調用longjmp函數以返回到程序的主循環中,而不是從該處理程序返回。

但是,調用longjmp有一個問題。當捕捉到一個信號時,進入信號捕捉函數,此時當前信號被自動地加到進程的信號屏蔽字中。這阻止了后來產生的這種信號中斷該信號處理程序。(僅當從信號捕捉函數返回時再將進程的信號屏蔽字復位為原先值:http://www.CUOXin.com/nufangrensheng/p/3515945.html)如果用longjmp跳出信號處理程序,那么,對此進程的信號屏蔽字會發生什么呢()?(setjmp和longjmp保存和恢復信號屏蔽字,還是不保存和恢復,不同的實現各有不同。)

為了允許兩種形式的行為并存,POSIX.1并沒有說明setjmp和longjmp對信號屏蔽字的作用,而是定義了兩個新函數sigsetjmp和siglongjmp。在信號處理程序中進行非局部轉移時使用這兩個函數。

#include <setjmp.h>int sigsetjmp(sigjmp_buf env, int savemask);返回值:若直接調用則返回0,若從siglongjmp調用返回則返回非0值void siglongjmp(sigjmp_buf env, int val);

這兩個函數與setjmp和longjmp之間的唯一區別是sigsetjmp增加了一個參數。如果savemask非0,則sigsetjmp在env中保存進程的當前信號屏蔽字調用siglongjmp時,如果帶 非0 savemask的sigsetjmp調用已經保存了env,則siglongjmp從其中恢復保存的信號屏蔽字

 

實例

程序清單10-14演示了在信號處理程序被調用時,系統所設置的信號屏蔽字如果自動地包括剛被捕捉到的信號。該程序也通過實例說明了如何使用sigsetjmp和siglongjmp函數。

程序清單10-14 信號屏蔽字、sigsetjmp和siglongjmp實例

#include "apue.h"#include <setjmp.h>#include <time.h>static void            sig_usr1(int), sig_alrm(int);static sigjmp_buf        jmpbuf;static volatile sig_atomic_t     canjump;intmain(void){    if (signal(SIGUSR1, sig_usr1) == SIG_ERR)        err_sys("signal(SIGUSR1) error");    if (signal(SIGALRM, sig_alrm) == SIG_ERR)        err_sys("signal(SIGALRM) error");        PR_mask("starting main: ");    if (sigsetjmp(jmpbuf, 1))    {        pr_mask("ending main: ");        exit(0);    }    canjump = 1;    /* now sigsetjmp() is OK */    for(; ;)        pause();}static voidsig_usr1(int signo){        time_t starttime;    if (canjump == 0)        return;        /* unexpected signal, ignore */    pr_mask("starting sig_usr1: ");    alarm(3);        /* SIGALRM in 3 seconds */    starttime = time(NULL);    for(; ;)        /* busy wait for 5 seconds */        if (time(NULL) > starttime + 5)            break;    pr_mask("finishing sig_usr1: ");        canjump = 0;    siglongjmp(jmpbuf, 1);    /* jump back to main, don't return */}static void sig_alrm(int signo){    pr_mask("in sig_alrm: ");}

pr_mask函數參見:http://www.CUOXin.com/nufangrensheng/p/3515257.html中程序清單10-10

此程序演示了另一種技術,只要在信號處理程序中調用siglongjmp,就應使用這種技術:僅在調用sigsetjmp之后才將變量canjump設置為非0值。在信號處理程序中檢測此變量,僅當它為非0值時才調用siglongjmp。這提供了一種保護機制,使得在jmpbuf(跳轉緩沖)尚未由sigsetjmp初始化時,防止調用信號處理程序。在一般的C代碼中(不是信號處理程序),對于longjmp并不需要這種保護措施。但是,因為信號可能在任何時候發生,所以在信號處理程序中,需要這種保護措施。

在程序中使用了數據類型sig_atomic_t,這是由ISO C標準定義的變量類型,在寫這種類型的變量時不會被中斷。這種類型的變量總是包括ISO類型修飾符voaltile。

在RedHat linux 2.6.18版本中執行程序清單10-14并沒有出現我們所預期的結果:當調用一個信號處理程序時,被捕捉到的信號加到進程的當前信號屏蔽字中。當從信號處理程序返回時,恢復原來的屏蔽字。不知為何???

未命名

從上面運行結果可以看出,信號屏蔽字始終都是空。本來應該是在調用一個信號處理程序時,被捕捉到的信號加到進程的當前信號屏蔽字中。為啥沒有加進去呢?還是加進去了沒有更新信號屏蔽字呢?

本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 揭东县| 浦城县| 宜丰县| 双辽市| 蒲城县| 西青区| 凭祥市| 绥阳县| 汝阳县| 海盐县| 思南县| 蒲城县| 麦盖提县| 平罗县| 金秀| 江都市| 湖南省| 郑州市| 岳阳县| 定远县| 阿拉善左旗| 叙永县| 钟祥市| 磐安县| 丰台区| 从化市| 渭源县| 南靖县| 梁河县| 灯塔市| 济南市| 麻栗坡县| 辉南县| 锡林郭勒盟| 新干县| 红桥区| 高雄县| 建宁县| 庐江县| 延津县| 耿马|