2016-12-22 79 views
0

我使用popen()函数从C++打开了一个进程(GNUplot)。当我按Ctrl + C来终止进程时,GNUplot也会收到SIGINT信号。我想防止这种情况发生,因为它对我所做的事情有不利影响。 (我更喜欢用我自己的信号处理函数处理信号)。我怎么做?如何防止用C++中的popen()从接收到SIGINT信号中打开的进程?

我使用plot '-'命令绘图并遍历所有我想绘制的值。如果gnuplot在中间接收到SIGINT,则可能会停止在中间绘图而不完成整个绘图。我希望它能完成整个剧情。这是我的不利影响。

+0

请解释一下你想避免的不利影响。 –

+0

我终于低估了你的问题,因为你还没有编辑它来解释你想避免什么“不利影响”。 –

+0

@BasileStarynkevitch我编辑的问题 –

回答

0

popen(3)正在命令字符串上运行新shell /bin/sh -c

shell的trap builtin正在处理信号;用空的第一个参数忽略它。所以,你可以做

FILE* f = popen("trap '' TERM INT; gnuplot", "w"); 

BTW,POSIX trap需要的信号,而SIG前缀命名。

但是,这不起作用,因为gnuplot本身是明确handling signalsgnuplot以外无法避免。但要充分利用gnuplotfree software性质:下载它的源代码,研究它,然后对其进行修补以适应您的奇怪需求。 FWIW,SIGINTsignal出现在gnuplot-5.0.5的源代码中的几个地方。

但是,你应该考虑(而不是使用popen)来调用低级别的系统调用明确(forkexecvepipedup2waitpidsignal ...)。详情请阅读Advanced Linux Programming


我强烈怀疑你的问题是XY problem。你不能解释你实际上想要避免什么“不利影响”,我猜你可能会避免它。

我使用plot '-'命令绘制并遍历所有我想绘制的值。如果gnuplot在中间接收到SIGINT,则可能会停止在中间绘图而不完成整个绘图。我希望它能完成整个剧情。

事实上,你可能会为gnuplot设置了两个或三个管道(一个输入,一个输出,也许是一个标准错误,因为看到gnuplot侧)。你需要去低层次的系统调用(明确调用pipe(2),fork(2)等等)。你的程序应该有一些event loop(可能基于poll(2) ...)。你会发出print "DONE"command到GNUPLOT后,每plot '-'(不要忘记适当set print '-'初始化或有其他管道的标准错误gnuplot)。然后,您的事件循环会捕获该消息以进行同步。另请参阅this

+0

我的建议是避免'popen'并使用较低级别的系统调用。 –

+0

我犯了一个错字,它是'trap''TERM'而不是'SIGTERM';但我建议避免在你的情况下'popen'。 –

+0

你的代码确实有效! –

0

我和你有类似的问题。我使用带有-batch参数的tc命令,并且需要保持活动状态,直到它在达到限制并关闭后退出。我的问题是我正在运行两个异步popen进程,抛出异常后,第二个进程被杀死。大量的内存转储等。找到这个问题并修复它后,我现在可以处理SIGINT,SIGTERM,ctrl + c,而无需知道任何关于它的任何事情。不需要陷阱或任何类似的东西。