我们可以使用 sigaction 将参数发送到信号处理程序吗?
Can we send parameters to a signal handler using sigaction?
我注意到 sigaction
有一个备用信号处理程序,当 SA_SIGINFO
标志为放。备用函数有一个 void* context
参数。现在,根据 APUE 书,这个参数可以转换成 ucontext_t
结构体。我的问题是我不能将它转换成我选择的任何结构吗?这样我就可以将自己的参数传递给信号处理程序。我注意到 Whosebug 中的 post 指出我们不能将参数传递给信号处理程序,因为它们是一个非常原始的功能。这可能吗 ?
This is a pointer to a ucontext_t
structure, cast to void *
. The structure pointed to by this field contains signal context information that was saved on the user-space stack by the kernel; ... Commonly, the handler function doesn't make any use of the third argument.
所以这个参数是一个特定于内核的指针,指向一个特殊的信号上下文。无法将其重新用于用户数据。
关于将参数传递给信号处理程序,我注意到的另一件重要事情是,能够将附加参数传递给信号处理程序的整个概念没有任何意义。信号处理程序是程序员未明确调用的东西。相反,它是在内核向程序发送信号时异步调用的东西。现在,即使可以将额外的参数传递给信号处理程序,什么将决定要发送哪个参数?假设信号处理程序的原型为 void func(int, void*);
。应用程序如何知道应该将哪个参数传递给第二个参数?这将是一个完全不确定的情况。
是的,您可以将用户提供的数据传递给信号处理程序 - 但不能使用上下文参数。相反,您必须使用 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
有一个备用信号处理程序,当 SA_SIGINFO
标志为放。备用函数有一个 void* context
参数。现在,根据 APUE 书,这个参数可以转换成 ucontext_t
结构体。我的问题是我不能将它转换成我选择的任何结构吗?这样我就可以将自己的参数传递给信号处理程序。我注意到 Whosebug 中的 post 指出我们不能将参数传递给信号处理程序,因为它们是一个非常原始的功能。这可能吗 ?
This is a pointer to a
ucontext_t
structure, cast tovoid *
. The structure pointed to by this field contains signal context information that was saved on the user-space stack by the kernel; ... Commonly, the handler function doesn't make any use of the third argument.
所以这个参数是一个特定于内核的指针,指向一个特殊的信号上下文。无法将其重新用于用户数据。
关于将参数传递给信号处理程序,我注意到的另一件重要事情是,能够将附加参数传递给信号处理程序的整个概念没有任何意义。信号处理程序是程序员未明确调用的东西。相反,它是在内核向程序发送信号时异步调用的东西。现在,即使可以将额外的参数传递给信号处理程序,什么将决定要发送哪个参数?假设信号处理程序的原型为 void func(int, void*);
。应用程序如何知道应该将哪个参数传递给第二个参数?这将是一个完全不确定的情况。
是的,您可以将用户提供的数据传递给信号处理程序 - 但不能使用上下文参数。相反,您必须使用 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.
。