[英]Can we send parameters to a signal handler using sigaction?
我注意到sigaction
有一個備用信號處理程序,在設置SA_SIGINFO
標志時調用它。 備用 function 有一個void* context
參數。 現在,根據APUE的書,這個參數可以轉換成一個ucontext_t
結構。 我的問題是,我不能將其轉換為我選擇的任何結構嗎? 這樣我就可以將自己的 arguments 傳遞給信號處理程序。 我注意到 stackoverflow 中有一篇文章指出我們不能將 arguments 傳遞給信號處理程序,因為它們是一個非常原始的功能。 這可能嗎?
是的,您可以將用戶提供的數據傳遞給信號處理程序——但不能使用 context 參數。 相反,您必須使用sigqueue(3)
通過安裝了SA_SIGINFO
的處理程序來引發信號。 這將填充作為處理程序的第二個參數的siginfo_t
結構的si_int
或si_ptr
字段,具體取決於sigqueue()
的第三個參數。
例子:
#include <signal.h>
#include <string.h>
#include <unistd.h>
void usr1_handler(int signo, siginfo_t *info, void *context) {
const char *msg = info->si_ptr;
write(STDOUT_FILENO, msg, strlen(msg));
}
int main(void) {
struct sigaction sa;
sa.sa_sigaction = usr1_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1, &sa, NULL);
const char *msg = "SIGUSR1 was called.\n";
sigqueue(getpid(), SIGUSR1, (union sigval){ .sival_ptr = (void *)msg });
return 0;
}
(當然,真正的代碼將包括錯誤檢查和處理)。
當編譯並運行時,這個玩具程序將打印SIGUSR1 was called.
.
從此sigaction
手冊頁:
這是一個指向
ucontext_t
結構的指針,轉換為void *
。 該字段指向的結構包含由 kernel 保存在用戶空間堆棧中的信號上下文信息; ... 通常,處理程序 function 不使用第三個參數。
所以這個參數是一個特定於內核的指針,指向一個特殊的信號上下文。 不可能將它重用於用戶數據。
關於將參數傳遞給信號處理程序,我注意到的另一件重要的事情是,能夠將附加參數傳遞給信號處理程序的整個概念沒有任何意義。 信號處理程序是程序員沒有明確調用的東西。 相反,當 kernel 向程序發送信號時,它會被異步調用。 現在,即使可以將額外的參數傳遞給信號處理程序,什么會確定要發送哪個參數? 假設信號處理程序有一個原型void func(int, void*);
. 應用程序如何知道應該將哪個參數傳遞給第二個參數? 這將是一個完全不確定的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.