我可以提供/传递任何参数给信号处理程序吗?
/* Signal handling */
struct sigaction act;
act.sa_handler = signal_handler;
/* some more settings */
现在,handler看起来像这样:
void signal_handler(int signo) {
/* some code */
}
如果我想做一些特别的事情,比如。删除临时文件,我可以提供这些文件作为这个处理程序的参数吗?
编辑0:谢谢你的回答。我们通常避免/不鼓励使用全局变量。在这种情况下,如果你有一个庞大的程序,事情可能会在不同的地方出错,你可能需要做很多清理工作。为什么API要这样设计?
8条答案
按热度按时间5w9g7ksd1#
您不能将自己的数据作为参数传递给信号处理程序。相反,你必须将参数存储在全局变量中。(如果你在安装信号处理程序后需要修改这些数据,一定要非常非常小心)。
此外,通常反对全局变量的论点在这里并不适用。信号处理程序 * 本身 * 是一个全局设置,因此不可能有几组不同的用户指定参数。(实际上,它不是完全全局的,而只是线程全局的。但是线程API将包括一些线程本地存储的机制,这正是您在本例中所需要的)。
jc3wubiy2#
一个信号处理器注册 * 已经是一个全局状态 *,等同于全局变量。所以使用全局变量传递参数并没有更大的冒犯。然而,这是一个巨大的错误(除非你是Maven,否则几乎可以肯定 * 未定义的行为 *!)从信号处理程序执行任何操作。如果您只是阻塞信号并从主程序循环中轮询它们,则可以避免所有这些问题。
e5njpo683#
这是一个很老的问题,但我想我可以告诉你一个很好的技巧,可以回答你的问题。不需要使用sigqueue或任何东西。
我也不喜欢使用全局变量,所以我必须找到一种聪明的方法,在我的情况下,发送一个void ptr(你可以稍后转换为任何适合你需要的)。
其实你可以这样做:
那么你的sighhandler看起来像这样:
你可能会问:那么如何获得 ptr呢?
具体操作如下: 初始化时 *
yyyllmsg4#
当然可以。你可以通过使用sigqueue()而不是通常的kill()将整数和指针传递给信号处理程序。
http://man7.org/linux/man-pages/man2/sigqueue.2.html
vh0rcniy5#
将文件名存储在全局变量中,然后从处理程序访问它。信号处理程序回调将只传递一个参数:导致问题的实际信号的ID(例如SIGINT、SIGTSTP)
编辑0:“必须有一个坚实的理由不允许参数的处理程序。”<--有一个中断向量(基本上,一组跳转地址到例程的每个可能的信号)。给定触发中断的方式,基于中断向量,调用特定函数。不幸的是,不清楚与变量关联的内存将在哪里被调用,并且根据中断,内存实际上可能被损坏。有一种方法可以解决这个问题,但是这样就不能利用现有的int 0x 80汇编指令(有些系统仍然在使用)
oxosxuxt6#
我认为你最好在sa_flags中使用SA_SIGINFO,这样处理程序将在siginfo_t中获得
void signal_handler(int sig, siginfo_t *info, void *secret)
,你可以提供你的参数。Ty:HAPPY代码ndh0cuux7#
你可以使用一个信号处理器,它是一个类的方法。然后该处理程序可以访问该类中的成员数据。我不完全确定Python在C信号()调用的背后做了什么,但它一定是重新确定数据的作用域?
我很惊讶这是有效的,但它确实有效。运行此命令,然后从另一个终端终止该进程。
xu3bshqb8#
尽管这是一个古老的问题,但这个问题今天仍然存在。基本上是关闭临时文件,正确终止线程等例如,可以使用这种逻辑:
基本上,在信号管理器中,设置了一个
sig_atomic_t
标志,它保证了对该变量的原子访问,并且volatile
向编译器发出信号,该变量不能被优化,因为它可能会发生意外的变化,例如信号的修改。在一系列线程的例子中,使用这个标志可以不使用全局变量,以一种安全的方式处理闭包