2017-07-03 682 views
1

sigaction手冊頁這是寫:sigaction:使用「void(* sa_sigaction)(int,siginfo_t *,void *);」

sa_sigaction還指定要與signum相關的動作。 該函數接收信號編號作爲其第一個參數, 指針指向siginfo_t作爲其第二個參數,並指向一個ucon- text_t(轉換爲void*)作爲其第三個參數。

所以我們可以傳遞參數給信號處理程序(通過void*),但我 找不到方法。 有沒有辦法把它放在任何地方?

實施例:

struct ping_val 
{ 
    int data1; 
    int data2; 
}; 

void ping(int sig, siginfo_t *siginf, void *ptr) 
{ 
    // .... 
} 

int main() 
{ 
    struct sigaction sa_ping; 
    ping_val foo; 
    foo.data1 = 3; 
    foo.data2 = 4; 
    sa_ping.sa_sigaction = ping; 
    sigemptyset(&sa_ping.sa_mask); 
    sa_ping.sa_flags = 0; 
    sigaction(SIGALRM, &sa_ping, NULL); 
    // .... 
} 

在哪裏可以在參數在平(在struct *有澆注)傳遞foo結構值???

+3

不,你不能任意數據傳遞到信號處理程序。您只能控制'sigaction'結構並且沒有用戶數據字段。另外,對於要調用的信號函數的三變量變體,您必須指定「SA_SIGINFO」標誌。 –

+2

你的困惑可能來自'ucontext_t'這個名字中的'u'?它並不代表「用戶數據」,它是引起信號的線程的堆棧結構。 –

回答

0

您不能將任何參數傳遞給信號處理程序,因爲您從來不會調用它。操作系統調用一個信號處理程序,它不知道任何關於您的參數的信息。

有一個信號處理程序與主程序通信的標準方式是通過全局(或文件範圍)變量。

0

一個信號處理程序接收siginfo_t結構包含一個union sigval si_value成員:

union sigval { 
    int sival_int; // Integer signal value 
    void *sival_ptr; // Pointer signal value 
} 

所以,如果你是一個單一的過程中發送信號(或叉之間,在某些情況下,我想),你可以發送指向一些數據的指針。

我知道的兩種方法將sigval值發送到信號處理程序:

如果使用timer_create創建一個定時器,你傳遞一個sigevent結構,其中包含了union sigval sigev_value成員。根據慣例,用戶代碼將設置sigev_value.sival_ptr爲定時器ID,以便信號處理程序可以根據需要區分多個定時器,但您可以將其設置爲任何void *值。

如果使用sigqueue(而不是killraise,故障等)發送的信號,你給它一個union sigval作爲參數。

0

你寫:

因此,我們可以將參數傳遞給信號處理[通過void *的ucontext_t說法],但我不能找到路。

有被發現沒有這樣的方式 - ucontext_t參數由系統自己設定,並且是指"the receiving thread's context that was interrupted when the signal was delivered."

(具體而言,by spec它含有至少到該中斷的上下文的引用,和這方面的特定機器的表示,也是當前上下文的堆棧和其設置封鎖信號。)

你可能不需要任何的這一點。如果你希望你的程序採取一些行動和/或修改在接收到信號的狀態,你可以在一個信號處理器(volatile sigatomic_t flags, self-pipes, platform-specific interfaces)安全使用策略的數量有限,但那麼你的主迴路當然可以按照剛剛收到SIGFOO的知識做你想做的事。

相關問題