我有一个带有线程的进程,该线程例如循环调用system("ping -qnc 1 192.168.1.1")
。
当我执行 CTRL + C 时,根据文档将忽略SIGINT:
在执行命令期间,
SIGCHLD
将被阻止,SIGINT
和SIGQUIT
在调用system()
的过程中将被忽略(这些信号将在执行 command 的子过程中根据其缺省值进行处理)。
这是为什么,如何使用 CTRL + C 退出我的进程?
答案 0 :(得分:2)
您的进程已阻止了这些信号,因此当用户按下Ctrl-C ping
时将被杀死,而您的程序也未被杀死。
如果您想要要被杀死的程序,则可以检查system()
的返回值,并查看ping
是否由于信号而被杀死。如果是这样,您可以采取适当的措施。
int status = system("ping -qnc 1 192.168.1.1");
if (WIFEXITED(status)) {
std::cout << "ping exited with exit code " << WEXITSTATUS(status) << std::endl;
}
else if (WIFSIGNALED(status)) {
std::cerr << "ping killed by signal " << WTERMSIG(status) << std::endl;
exit(1);
}
else {
std::cerr << "ping exited for some other reason" << std::endl;
}
答案 1 :(得分:2)
POSIX.1-2017指出system()
的调用“不是线程安全的”。
通常来说,在多线程环境中调用system()
不是一个好主意。该功能的目的就像“运行辅助进程并等待其完成”。这就是为什么信号被捕获和阻塞的原因。
如果您希望您的主进程被某种方式杀死(例如,通过按Ctrl + C组合键),那么您可能更愿意使用popen()
。
答案 2 :(得分:0)
最后,只要您明确放弃命令输出(popen
)或在cmd > /dev/null
之前读取输出,pclose
就可以正常工作,但是我最终还是选择了boost::process::system()
使用execve
并且不捕获SIGINT
的情况:
bool ping(const std::string& ip,
uint32_t count = 1,
std::chrono::seconds timeout = 1s)
(
return (0 ==
bp::system(bp::exe = "/bin/ping",
bp::args = { "-q",
"-w", std::to_string(timeout.count()),
"-c", std::to_string(count),
ip },
bp::std_out > bp::null));
}
popen
的唯一“优势”是 ctrl + c 也会像系统一样向孩子发出信号,但不会捕获信号。就我而言,我实际上是在等待孩子正常完成。