提供/传递参数给信号处理程序

我可以提供/传递任何参数给信号处理程序吗?

/* Signal handling */ struct sigaction act; act.sa_handler = signal_handler; /* some more settings */ 

现在,处理程序看起来像这样:

 void signal_handler(int signo) { /* some code */ } 

如果我想做一些特别的事情,即删除临时文件,我可以提供这些文件作为参数到这个处理程序?

编辑0:感谢您的答案。 我们通常避免/阻止使用全局variables。 而在这种情况下,如果你有一个巨大的程序,事情可能会在不同的地方出错,你可能需要做很多清理工作。 为什么这样deviseAPI?

您不能将自己的数据作为parameter passing给信号处理程序。 相反,您必须将参数存储在全局variables中。 (如果在安装信号处理程序之后需要更改这些数据,那么确实要小心)。

回复编辑0:历史原因。 信号是一个非常古老而又非常低级的devise。 基本上你只是给内核一个地址给一些机器代码,并要求它去这个特定的地址,如果发生这样的事情。 我们重新回到了“便携式汇编程序”的思维模式,内核提供了一个简单的基本服务,无论用户进程可以合理预期为自己,它必须自己做。

另外,反对全局variables的通常的论据并不适用于此。 信号处理程序本身是一个全局设置,所以没有相关的可能性,有几组不同的用户指定的参数。 (嗯,实际上它不是全局的,而只是全局的,但是线程API将包含一些线程本地存储的机制,这正是你在这种情况下所需要的)。

信号处理程序注册已经是一个等同于全局variables的全局状态 。 所以使用全局variables来传递参数并不是什么大问题。 然而,这是一个巨大的错误(几乎可以肯定, 没有定义的行为,除非你是一个专家!)无论如何,从信号处理程序做任何事情。 如果您只是阻止信号并从主程序循环中进行轮询,则可以避免所有这些问题。

将文件的名称存储在全局variables中,然后从处理程序中访问它。 信号处理程序callback将只传递一个参数:导致问题的实际信号的标识(例如SIGINT,SIGTSTP)

编辑0:“不允许处理程序的参数一定有一个坚实的理由。” 有一个中断向量(基本上,每个可能的信号都有一组跳转地址)。 鉴于中断的触发方式,基于中断向量,调用一个特定的函数。 不幸的是,不清楚与variables关联的内存在哪里被调用,并且取决于内存实际上可能被破坏的中断。 有一种方法来解决它,但是你不能利用现有的int 0x80汇编指令(一些系统仍然使用)

这是一个非常古老的问题,但我想我可以告诉你一个很好的技巧,可以解决你的问题。 不需要使用sigqueue或其他。

我也不喜欢使用全局variables,所以我必须find一个聪明的方法,在我的情况下,发送一个无效的ptr(你可以稍后投射到任何适合你的需要)。

其实你可以这样做:

 signal(SIGWHATEVER, (void (*)(int))sighandler); // Yes it works ! Even with -Wall -Wextra -Werror using gcc 

然后你的sighandler看起来像这样:

 int sighandler(const int signal, void *ptr) // Actually void can be replaced with anything you want , MAGIC ! 

你可能会问:如何获得* ptr呢?

这是如何: 在初始化

 signal(SIGWHATEVER, (void (*)(int))sighandler) sighandler(FAKE_SIGNAL, your_ptr); 

在你的sighandler函数中

 int sighandler(const int signal, void *ptr) { static my_struct saved = NULL; if (saved == NULL) saved = ptr; if (signal == SIGNALWHATEVER) // DO YOUR STUFF OR FREE YOUR PTR return (0); } 

你可以使用一个信号处理程序,这是一个类的方法。 然后,该处理程序可以访问该类的成员数据。 我并不完全确定Python在C signal()调用下做了些什么,但是它必须重新确定数据范围?

我很惊讶,这是有效的,但它的确如此。 运行这个,然后杀死另一个terminal的进程。

 import os, signal, time class someclass: def __init__(self): self.myvalue = "something initialized not globally defined" signal.signal(signal.SIGTERM, self.myHandler) def myHandler(self, s, f): # WTF u can do this? print "HEY I CAUGHT IT, AND CHECK THIS OUT", self.myvalue print "Making an object" a = someclass() while 1: print "sleeping. Kill me now." time.sleep(60) 

您可以使用sigqueue()而不是通常的kill()将整数和指针传递给信号处理程序。

http://man7.org/linux/man-pages/man2/sigqueue.2.html