2011-05-03 26 views
6

我注册的主要的处理程序SIGTERM这样的:反正有参数传递给信号处理程序吗?

signal(SIGTERM, sigterm_handler); 

而且处理程序是一个简单的:

void sigterm_handler() 
{ exit(1); } 

如果我需要传递给处理程序的几个参数像2个指针或其他什么?如何在信号功能中注册处理程序?或者至少......无论如何要实现这一目标?

注意:整个过程由第三方进程杀死,而不是自己。但在结束之前,我需要手动释放一些结构并将它们写入文件。

+1

仅供参考,不调用exit()的信号处理函数里面 - 它不是异步信号安全的,因为它刷新stdio的缓冲区。在信号处理程序中使用_exit()。 – lightdee 2012-03-26 20:42:29

+0

这真的很老了,它没有被接受的答案,但有一个重复的更新一点,只是重定向任何我标记为重复的读者。 – 2015-07-30 18:47:03

回答

6

你在哪里打算从传递参数?发送信号的唯一时间将是一种合理的方式来做你正在做的事情,当你正在终止的进程是而不是进程本身,但在这种情况下,指针将是没有意义的。你可以通过一个指针sigqueue函数和SA_SIGINFO类型的信号处理程序,但它在我看来像你不明白信号或有任何充分的理由使用它们摆在首位。只是做一个函数调用,当你想退出,而不是提高信号......

+0

编辑过的文章:这个过程被第三方过程杀死,而不是自己。但在结束之前,我需要手动释放一些结构并将它们写入文件。 – 2011-05-03 21:19:02

+0

然后,您需要将指向该数据的指针存储在全局变量中,或者阻止信号并使用sigwait而不是信号处理程序来处理它。 – 2011-05-03 21:34:41

0

不能传递的参数来处理 - 因为你不是一个调用处理。处理程序将从您控制之外的某个地方调用。

您注册了一个处理程序,可以调用signalsigaction

心连心

马里奥

+1

也许OP只是希望程序中其他地方的某些指针可用于信号处理程序,但不由生成该信号的代码指定。如果是这样的话,全局变量是(丑陋的)解决方案。另外,'SIGTERM'可以被阻塞,并用'sigwait'处理,而不是异步处理。 – 2011-05-03 20:44:46

+0

是真的,但它们不是参数;-) – 2011-05-03 20:52:01

0

信号通常都以异步方式,从程序中的特定点没有意思,因此你不能正常传递参数。如果我在程序运行时按下control-C,信号处理程序应该得到什么指针?

你只能通过有意义的参数(如果C将允许,这事实并非如此),如果你构建你的程序中的信号,并故意提高它,在这种情况下,你应该调用一个函数来代替。

所以,如果你想打电话给你的程序的东西,使用的功能。如果你想要一个函数,如果有一个外部事件,它不知道你正在处理什么,使用一个信号处理程序。

+0

编辑后:进程被第三方进程终止,而不是自己。但在结束之前,我需要手动释放一些结构并将它们写入文件。 – 2011-05-03 21:19:58

+0

@ hysoka44:你仍然无法传递任何指针。如果您喜欢,您可以在全局变量中留下指向数据结构的指针。然后你需要弄清楚你可以在信号处理器内可靠地做些什么。由于它是异步调用的,因此这个过程可能处于做某些事情的中间,比如I/O,并且这很容易让信号处理程序的一部分工作将数据结构写出来。或者它可能处于堆操作的中间,堆可能不是一致的状态。获取信号处理程序来做可靠的任何事情是很困难的。 – 2011-05-03 21:34:04

+0

我会去找全局变量。没办法阻止信号处理程序调用留下可能不一致的状态,对吧?我在想:一旦处理程序被调用,我检查之前是否调用过它(检查全局int):如果不是,则标记int并返回其他操作,然后执行需要并退出的操作。在我的主函数中,我可以设置一些“安全点”来检查处理程序是否被调用,如果是这样,然后再次调用它(但现在它不会返回,但它会从开始就做我所需要的)。所以我不会有不稳定的状态。我的想象力会飞得很高吗? – 2011-05-03 21:44:29

3

只需使用一个全局变量。正如其他人指出的那样,您的信号处理程序将由不受您控制的调用堆栈调用。

您可能会考虑使用setjmp()longjmp()将控制从您的信号处理程序传输到先前执行的代码路径。这种老派的方式对你来说真的很有趣。

相关问题