我用popen()函数从C ++打开了一个进程(GNUplot)。当我按Ctrl + C终止进程时,GNUplot也会收到SIGINT信号。我想防止这种情况发生,因为它对我所做的事情有不利影响。 (我更喜欢使用自己的信号处理函数处理信号)。我怎么做?
我使用plot '-'
命令绘制并迭代我想要绘制的所有值。如果gnuplot在中间接收到SIGINT,它可能会停止在中间绘图而不完成整个绘图。我希望它能完成整个情节。这是我的不利影响。
popen(3)正在命令字符串上运行一个新的shell /bin/sh -c
。
壳的trap
builtin处理信号;有一个空的第一个参数,它忽略了它。所以你可以做到
FILE* f = popen("trap '' TERM INT; gnuplot", "w");
顺便说一下,POSIX trap
要求在没有SIG
前缀的情况下命名信号。
但这不起作用,因为gnuplot
本身明确是handling signals。没有办法避免在gnuplot
之外。但是利用free software的gnuplot
特性:下载它的源代码,研究它,并根据你的奇怪需求进行修补。 FWIW,SIGINT
和signal
出现在gnuplot-5.0.5
源代码的几个地方。
但是,您应该考虑(而不是使用popen
)明确调用低级系统调用(fork
,execve
,pipe
,dup2
,waitpid
,signal
......)。阅读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。
我和你有类似的问题。我正在使用tc命令和-batch参数,我需要保持它活着,直到它达到限制后退出并关闭。我的问题是我正在运行两个异步popen进程,并在抛出异常后,第二个进程被终止。很多内存转储等。在找到这个问题并修复它后,我现在可以处理SIGINT,SIGTERM,ctrl + c,而不需要知道任何关于它的知识。不需要陷阱或任何类似的东西。