如何防止使用C ++中的popen()打开进程接收SIGINT信号?

时间:2016-12-22 07:22:34

标签: c++ signals popen sigterm

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

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

2 个答案:

答案 0 :(得分:0)

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

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

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

BTW,POSIX trap要求信号的名称不带SIG前缀。

但这不起作用,因为gnuplot本身明确地 handling signals。在gnuplot之外无法避免这种情况。但是利用free softwaregnuplot性质:下载其源代码,研究它并修补它以满足您的奇怪需求。 FWIW,SIGINTsignal出现在gnuplot-5.0.5源代码的多个位置。

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

我强烈怀疑你的问题是XY problem。你没有解释你真正想要避免的“不利影响”,我猜你可能会避免它。

  

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

实际上,您可以为gnuplot设置两个或三个管道(一个用于输入,一个用于输出,可能一个用于stderr,如gnuplot侧所示)。您需要进行低级系统调用(显式调用pipe(2)fork(2)等等...)。您的程序应该有一些event loop(可能基于poll(2) ...)。并且您会在每print "DONE"之后向gnuplot发送plot '-' command(不要忘记使用适当的set print '-'进行初始化,或者为 stderr <使用另一个管道{em} of gnuplot)。然后,您的事件循环将捕获要同步的DONE消息。另请阅读this

答案 1 :(得分:0)

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