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

首頁 > 學(xué)院 > 操作系統(tǒng) > 正文

信號(hào)之sigaction函數(shù)

2024-06-28 13:28:27
字體:
供稿:網(wǎng)友
信號(hào)之sigaction函數(shù)

sigaction函數(shù)的功能是檢查或修改與指定信號(hào)相關(guān)聯(lián)的處理動(dòng)作(或同時(shí)執(zhí)行這兩種操作)。

#include <signal.h>int sigaction( int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);返回值:若成功則返回0,若出錯(cuò)則返回-1

其中,參數(shù)signo是要檢測(cè)或修改其具體動(dòng)作的信號(hào)編號(hào)。若act指針非空,則要修改其動(dòng)作。如果oact指針非空,則系統(tǒng)經(jīng)由oact指針返回該信號(hào)的上一個(gè)動(dòng)作。此函數(shù)使用下列結(jié)構(gòu):

struct sigaction {    void    (*sa_handler)(int);    /* addr of signal handler, or SIG_IGN, or SIG_DFL */    sigset_t    sa_mask;           /* additional signals to block */    int    sa_flags;               /* signal options */    /* alternate handler */    void    (*sa_sigaction)(int, siginfo_t *, void *);};

當(dāng)更改信號(hào)動(dòng)作時(shí),如果sa_handler字段包含一個(gè)信號(hào)捕捉函數(shù)的地址(與常量SIG_IGN或SIG_DFL相對(duì)),則sa_mask字段說明了一個(gè)信號(hào)集,在調(diào)用該信號(hào)捕捉函數(shù)之前,這一信號(hào)集要加到進(jìn)程的信號(hào)屏蔽字中。僅當(dāng)從信號(hào)捕捉函數(shù)返回時(shí)再將進(jìn)程的信號(hào)屏蔽字復(fù)位為原先值。這樣,在調(diào)用信號(hào)處理程序時(shí)就能阻塞某些信號(hào)。在信號(hào)處理程序被調(diào)用時(shí),操作系統(tǒng)建立的新信號(hào)屏蔽字包括正被遞送的信號(hào)。因此保證了在處理一個(gè)給定的信號(hào)時(shí),如果這種信號(hào)再次發(fā)生,那么它會(huì)被阻塞到對(duì)前一個(gè)信號(hào)的處理結(jié)束為止。

一旦對(duì)給定的信號(hào)設(shè)置了一個(gè)動(dòng)作,那么在調(diào)用sigaction顯式地改變它之前,該設(shè)置就一直有效。(早期版本并非如此,而是:在進(jìn)程每次接到信號(hào)對(duì)其進(jìn)行處理時(shí),隨即將該信號(hào)動(dòng)作復(fù)位為默認(rèn)值。見http://www.CUOXin.com/nufangrensheng/p/3515035.html)

act結(jié)構(gòu)的sa_flags字段指定對(duì)信號(hào)進(jìn)行處理的各個(gè)選項(xiàng)。

表10-5 處理每個(gè)信號(hào)的選項(xiàng)標(biāo)志(sa_flags)

2012082515302617

sa_sigaction字段是一個(gè)替代的信號(hào)處理程序,當(dāng)在sigaction結(jié)構(gòu)中使用了SA_SIGINFO標(biāo)志時(shí),使用該信號(hào)處理程序。對(duì)于sa_sigaction字段和sa_handler字段這兩者,其實(shí)現(xiàn)可能使用同一存儲(chǔ)區(qū),所以應(yīng)用程序只能一次使用這兩個(gè)字段中的一個(gè)。

通常,按下列方式調(diào)用信號(hào)處理程序:

void handler(int signo);

但是,如果設(shè)置了SA_SIGINFO標(biāo)志,那么按下列方式調(diào)用信號(hào)處理程序:

void handler(int signo, siginfo_t *info, void *context);

siginfo_t結(jié)構(gòu)包含了信號(hào)產(chǎn)生原因的有關(guān)信息。該結(jié)構(gòu)的大致樣式如下所示:

struct siginfo {    int      si_signo;        /* signal number */    int      si_errno;        /* if nonzero, errno value from <errno.h> */    int      si_code;         /* additional info (depends on signal) */    pid_t    si_pid;          /* sending PRocess ID */    uid_t    si_uid;          /* sending process real user ID */    void    *si_addr;         /* address that caused the fault */    int      si_status;       /* exit value or signal number */    long     si_band;         /* band number for SIGPOLL */    /* possibly other fields also */};

各種信號(hào)的si_code值(包括上面的相關(guān)數(shù)據(jù)結(jié)構(gòu)和標(biāo)志選項(xiàng)),可通過man sigaction命令進(jìn)行查看。

若信號(hào)是SIGCHLD,則將設(shè)置si_pid、si_status和si_uid字段。

若信號(hào)是SIGILL或SIGSEGV,則si_addr包含造成故障的根源地址,盡管該地址可能并不準(zhǔn)確。

若信號(hào)是SIGPOLL,那么si_band字段將包含STREAMS消息的優(yōu)先級(jí)(priority band),該消息產(chǎn)生POLL_IN、POLL_OUT或POLL_MSG事件。

si_errno字段包含錯(cuò)誤編號(hào),它對(duì)應(yīng)于引發(fā)信號(hào)產(chǎn)生的條件,并由實(shí)現(xiàn)定義。

信號(hào)處理程序的context參數(shù)是無類型指針,它可被強(qiáng)制轉(zhuǎn)換為ucntext_t結(jié)構(gòu)類型,用于標(biāo)識(shí)信號(hào)傳遞時(shí)進(jìn)程的上下文。

實(shí)例:signal函數(shù)

現(xiàn)在用sigaction實(shí)現(xiàn)signal函數(shù)。很多平臺(tái)都是這樣做的。

程序清單10-12 用sigaction實(shí)現(xiàn)signal函數(shù)

#include "apue.h"/* Reliable version of signal(), using POSIX sigaction(). */Sigfunc *signal(int signo, Sigfunc *func){    struct sigaction    act, oact;        act.sa_handler = func;    sigemptyset(&act.sa_mask);    act.sa_flags = 0;    if(signo == SIGALRM)    {#ifdef    SA_INTERRUPT        act.sa_flags |= SA_INTERRUPT;#endif    }    else    {#ifdef    SA_RESTART        act.sa_flags |= SA_RESTART;#endif    }    if(sigaction(signo, &act, &oact) < 0)        return(SIG_ERR);    return(oact.sa_handler);}

注意,必須用sigemptyset函數(shù)初始化act結(jié)構(gòu)的sa_mask成員。不能保證:act.sa_mask = 0;會(huì)做同樣的事情。

對(duì)除SIGALRM以外的所有信號(hào),我們都有嘗試設(shè)置SA_RESTART標(biāo)志,于是被這些信號(hào)中斷的系統(tǒng)調(diào)用都能自動(dòng)重啟動(dòng)。不希望重啟動(dòng)由SIGALRM信號(hào)中斷的系統(tǒng)調(diào)用的原因是:我們希望對(duì)I/O操作可以設(shè)置時(shí)間限制。

實(shí)例:signal_intr函數(shù)

程序清單10-13是signal函數(shù)的另一種版本,它力圖阻止任何被中斷的系統(tǒng)調(diào)用重啟動(dòng)。

程序清單10-13 signal_intr函數(shù)

#include "apue.h"Sigfunc *signal_intr(int signo, Sigfunc *func){    struct sigaction     act, oact;    act.sa_handler = func;    sigemptyset(&act.sa_mask);    act.sa_flags = 0;#ifdef    SA_INTERRUPT    act.sa_flags |= SA_INTERRUPT;#endif    if(sigaction(signo, &act, &oact) < 0)        return(SIG_ERR);    return(oact.sa_handler);}

如果系統(tǒng)定義了SA_INTERRUPT標(biāo)志,那么為了提高可移植性,我們?cè)趕a_flags中增加該標(biāo)志,這樣也就阻止了被中斷的系統(tǒng)調(diào)用重啟動(dòng)。

本篇博文內(nèi)容摘自《UNIX環(huán)境高級(jí)編程》(第二版),僅作個(gè)人學(xué)習(xí)記錄所用。關(guān)于本書可參考:http://www.apuebook.com/


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宿松县| 信阳市| 十堰市| 奉贤区| 昭觉县| 汉阴县| 凤城市| 绥中县| 宁化县| 万载县| 禄劝| 靖西县| 泰顺县| 利川市| 余姚市| 开阳县| 水富县| 安溪县| 禹城市| 保靖县| 怀化市| 苍溪县| 左权县| 丹阳市| 湟源县| 乾安县| 仪征市| 台山市| 宁陵县| 石景山区| 墨脱县| 和龙市| 腾冲县| 衡南县| 郴州市| 区。| 阳谷县| 治多县| 揭阳市| 白城市| 马边|