簡體   English   中英

我們可以使用 sigaction 將參數發送到信號處理程序嗎?

[英]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_intsi_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM