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

问题描述 投票:0回答:2

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

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

c++ signals popen sigterm
2个回答
0
投票

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

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

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

顺便说一下,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"之后发送一个command plot '-'到gnuplot(不要忘记用适当的set print '-'初始化或为gnuplot的stderr另一个管道)。然后,您的事件循环将捕获DONE消息以进行同步。另请阅读this


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.