调用系统(3)时忽略了SIGINT
SIGINT ignored while calling system(3)
我有一个进程,其中有一个线程在循环中调用例如:system("ping -qnc 1 192.168.1.1")
当我执行CTRL+C时,根据文档,SIGINT被忽略:
在执行命令期间,
SIGCHLD
将被阻止,SIGINT
和在调用system()
的进程中,SIGQUIT
将被忽略(这些信号将在执行命令的子进程中根据其默认值进行处理(。
为什么会这样,我该怎么做才能用CTRL+C退出我的进程?
您的进程阻止了这些信号,因此当用户按下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;
}
POSIX.1-2017指出system()
调用"不需要是线程安全的"。
一般来说,在多线程环境中调用system()
不是一个好主意。该函数的目的类似于"运行辅助进程并等待它完成"。这就是信号被捕获和阻断的原因。
如果您希望您的主进程以某种方式被终止(例如按Ctrl+C(,那么您可能更喜欢使用popen()
。
总之,只要明确放弃命令输出(cmd > /dev/null
(或在pclose
之前读取输出,popen
就可以正常工作,但我最终选择了使用execve
且不捕获SIGINT
的boost::process::system()
:
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也会像系统一样向孩子发出信号,但不会捕获信号。在我的情况下,我实际上想等待孩子正常完成。
相关文章:
- C++,系统无法执行指定的程序
- 在UNIX系统中使用DIR查找文件的字节大小
- 错误处理.将系统错误代码映射到泛型
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 在C++游戏中与库存系统作斗争
- 文件系统:复制功能的速度秘诀是什么
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 在gtest.中使用fff.h模拟系统API
- 如何制作无限制照明系统
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 如何传递多个 std::文件系统选项?
- 遍历顺序由 std::文件系统directory_iterator给出
- C++系统找不到指定的文件错误
- 系统参数信息A 与 SPI_GETMOUSE 返回 0
- libstdc++ 文件系统中未初始化的用法?
- 如何在ECS框架中更新组件数据和通知系统
- boost::文件系统::recursive_directory_iterator多线程安全
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- 调用系统(3)时忽略了SIGINT