sigqueue函數 處理序間通訊 訊號的發送攜帶資料

來源:互聯網
上載者:User

今天只看SIGQUEUE函數:聲明:其中有部分

http://www.bccn.net/Article/kfyy/vc/jszl/200708/5849.html(編程中國)的摘抄:

3、sigqueue()
#include <sys/types.h>
#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval val)
調用成功返回 0;否則,返回 -1。

sigqueue()是比較新的發送訊號系統調用,主要是針對即時訊號提出的(當然也支援前32種),支援訊號帶有參數,與函數sigaction()配合使用。

sigqueue的第一個參數是指定接收訊號的進程ID,第二個參數確定即將發送的訊號,第三個參數是一個聯合資料結構union sigval,指定了訊號傳遞的參數,即通常所說的4位元組值。

 


typedef union sigval {
int sival_int;
void *sival_ptr;
}sigval_t;

sigqueue()比kill()傳遞了更多的附加資訊,但sigqueue()只能向一個進程發送訊號,而不能發送訊號給一個進程組。如果
signo=0,將會執行錯誤檢查,但實際上不發送任何訊號,0值訊號可用於檢查pid的有效性以及當前進程是否有許可權向目標進程發送訊號。

在調用sigqueue時,sigval_t指定的資訊會拷貝到3參數訊號處理函數(3參數訊號處理函數指的是訊號處理函數由sigaction安
裝,並設定了sa_sigaction指標,稍後將闡述)的siginfo_t結構中,這樣訊號處理函數就可以處理這些資訊了。由於sigqueue系統
調用支援發送帶參數訊號,所以比kill()系統調用的功能要靈活和強大得多。

註:sigqueue()發送非即時訊號時,第三個參數包含的資訊仍然能夠傳遞給訊號處理函數; sigqueue()發送非即時訊號時,仍然不支援排隊,即在訊號處理函數執行過程中到來的所有相同訊號,都被合并為一個訊號。

***************************************************************************************************************************

根據以上對SIGQUEUE函數的講解,

在調用sigqueue時,sigval_t指定的資訊會拷貝到3參數訊號處理函數(3參數訊號處理函數指的是訊號處理函數由sigaction安裝,並
設定了sa_sigaction指標,稍後將闡述)的siginfo_t結構中,這樣訊號處理函數就可以處理這些資訊了。由於sigqueue系統調用支
持發送帶參數訊號

 

這一部分較難理解:

SIGQUEUE函數的第三個參數是拷貝到SIGQUEUE函數中的,這裡有一個3參數SIGQUEUE函數,以下是關於SIGACTION函數此方面的詳解:

***********************************************SIGACTION*************************************************************

sigaction()
#include <signal.h>
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));

sigaction函數用於改變進程接收到特定訊號後的行為。該函數的第一個參數為訊號的值,可以為除SIGKILL及SIGSTOP外的任何一個
特定有效訊號(為這兩個訊號定義自己的處理函數,將導致訊號安裝錯誤)。第二個參數是指向結構sigaction的一個執行個體的指標,在結構
sigaction的執行個體中,指定了對特定訊號的處理,可以為空白,進程會以預設方式對訊號處理;第三個參數oldact指向的對象用來儲存原來對相應訊號
的處理,可指定oldact為NULL。如果把第二、第三個參數都設為NULL,那麼該函數可用於檢查訊號的有效性。

第二個參數最為重要,其中包含了對指定訊號的處理、訊號所傳遞的資訊、訊號處理函數執行過程中應屏蔽掉

sigaction的結構形態如下:
struct sigaction {
    void (*sa_handler)(int);
    void (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t sa_mask;
    int sa_flags;
    void (*sa_restorer)(void);
}

參數:

在一些體繫上,sa_handler和sa_sigaction共用一個聯合體(union),所以不要同時指定兩個欄位的值。

sa_restorer欄位已淘汰,不應該再被使用。

sa_handler欄位指定與signum訊號關聯的行為,可能是SIG_DFL預設行為,SIG_IGN忽略接送到的訊號,或者一個訊號處理函數指標。這個函數以一個訊號編碼作為它的唯一參數

如果sa_flags中存在SA_SIGINFO標誌,那麼sa_sigaction將作為signum訊號的處理函數。這個函數的第一參數是訊號編碼,第二參數是siginfo_t結構的指標,第三參數是ucontext_t結構指標(造型為void *)。

sa_mask指定訊號處理函數執行的過程中應被阻塞的訊號。另外,除了SA_NODEFER標誌被指定外,觸發訊號處理函數執行的那個訊號也會被阻塞。

sa_flags指定一系列用於修改訊號處理過程行為的標誌,由下面的0個或多個標誌通過or運算組合而成:
 SA_NOCLDSTOP //此標誌為on時,假如signum的值是SIGCHLD,則在子進程停止或恢複執行時不會傳訊號給調用本系統調用的進程。
 SA_NOCLDWAIT //此標誌為on時,當調用此系統調用的進程之子進程終止時,系統不會建立zombie進程。
 SA_RESETHAND //此標誌為on時,訊號處理函數接收到訊號後,會先將對訊號處理的方式設為預設方式,而且當函數處理該訊號時,後來發生的訊號將不會被阻塞。
 SA_ONSTACK //如果利用sigaltstack()建立訊號專用堆棧,則此標誌會把所有訊號送往該堆棧。
 SA_RESTART //此標誌為on時,核心會自動重啟訊號中斷的系統調用,否則返回EINTR錯誤值。
 SA_NODEFER //當此標誌為on時,在訊號處理函數處置訊號的時段中,核心程式不會把這個間隙中產生的訊號阻塞。
 SA_SIGINFO //此標誌為on時,指定訊號處理函數需要三個參數,所以應使用sa_sigaction替代sa_handler。

 

看看標頭檔:

#define SA_SIGINFO    4          /* Invoke signal-catching function with
 57                                     three arguments instead of one.  */

這是標頭檔中對SA-SIGINFO的描述****************************************************************

好啦,到目前我們捋捋思路:

函數sigaction()的第二個參數指向一個struct sigaction結構的指標,這個結構中有兩個函數指標

void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);

他們都可以作為訊號處理函數,使用那一個就要看SA-FLAGS是否標誌位SA-SIGINFO,標誌啦,就用sa_sigaction指標指向的函數,沒有標誌,就使用sa_handler指向的函數。

由_sa_handler指定的處理函數只有一個參數,即訊號值,所以訊號不能傳遞除訊號值之外的任何資訊;由_sa_sigaction是指定的訊號處
理函數帶有三個參數,是為即時訊號而設的(當然同樣支援非即時訊號),它指定一個3參數訊號處理函數。第一個參數為訊號值,第三個參數沒有使用
(posix沒有規範使用該參數的標準),第二個參數是指向siginfo_t結構的指標,結構中包含訊號攜帶的資料值,參數所指向的結構如下:

sa_sigaction第二個參數siginfo_t結構的原型如下:

siginfo_t {
    int      si_signo;  /* Signal number */
    int      si_errno;  /* An errno value */
    int      si_code;   /* Signal code */
    pid_t    si_pid;    /* Sending process ID */
    uid_t    si_uid;    /* Real user ID of sending process */
    int      si_status; /* Exit value or signal */
    clock_t  si_utime;  /* User time consumed */
    clock_t  si_stime;  /* System time consumed */
    sigval_t si_value;  /* Signal value */

    int      si_int;    /* POSIX.1b signal */
    void *   si_ptr;    /* POSIX.1b signal */
    void *   si_addr;   /* Memory location which caused fault */
    int      si_band;   /* Band event */
    int      si_fd;     /* File descriptor */
}

看見加黑的結構體沒有,這個才是我們今天堯討論的

他的定義和sigval這個結構定義在一個標頭檔中<siginfo.h>

下面是sigval的結構體定義:

/* Type for data associated with a signal.  */
 33 typedef union sigval
 34   {
 35     int sival_int;
 36     void *sival_ptr;
 37   } sigval_t;

採用聯合資料結構,說明siginfo_t結構中的si_value要麼持有一個4位元組的整數值,要麼持有一個指標,這就構成了與訊號相關的資料。在訊號
的處理函數中,包含這樣的訊號相關資料指標,但沒有規定具體如何對這些資料進行操作,操作方法應該由程式開發人員根據具體任務事先約定。

************************************************SIGACTION***************************************************************

現在回到SIGQUEUE函數:

在調用sigqueue時,sigval_t指定的資訊會拷貝到3參數訊號處理函數(3參數訊號處理函數指的是訊號處理函數由sigaction安裝,並
設定了sa_sigaction指標)的siginfo_t結構中,這樣訊號處理函數就可以處理這些資訊了。由於sigqueue系統調用支
持發送帶參數訊號,所以比kill()系統調用的功能要靈活和強大得多。

現在就好理解這段話啦!!!


聯繫我們

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