C语言 我们可以使用 sigaction 将参数发送到信号处理程序吗?



我注意到sigaction有一个备用信号处理程序,在设置SA_SIGINFO标志时调用。备用函数具有void* context参数。现在,根据APUE的书,这个参数可以转换为ucontext_t结构。我的问题是,我不能将其转换为我选择的任何结构吗?这样我就可以将自己的参数传递到信号处理程序中。我注意到 stackoverflow 中的一篇文章指出我们不能将参数传递给信号处理程序,因为它们是一个非常原始的功能。这可能吗?

是的,您可以将用户提供的数据传递给信号处理程序 - 但不能使用 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 *。此字段指向的结构包含内核保存在用户空间堆栈上的信号上下文信息;...通常,处理程序函数不使用第三个参数。

因此,此参数是指向特殊信号上下文的特定于内核的指针。无法将其重用于用户数据。

关于将参数传递给信号处理程序,我注意到的另一件重要事情是,能够将附加参数传递给信号处理程序的整个概念没有任何意义。信号处理程序是程序员未显式调用的东西。相反,它是在内核向程序发送信号时异步调用的东西。现在,即使可以将附加参数传递给信号处理程序,什么将决定要发送哪个参数?假设信号处理程序有一个void func(int, void*);的原型。应用程序如何知道应该将哪个参数传递给第二个参数?这将是一个完全不确定的情况。

相关内容

  • 没有找到相关文章

最新更新