我通过const
从stdin
读取用户输入,我希望能够通过SIGINT退出程序。不幸的是,std::getline()
似乎没有在任何信号上醒来。因此,下面的代码只有在按下CTRL-C 和 RETURN后才会中止。
std::getline()
为什么会这样?除了用户输入之外,我有没有机会唤醒#include <csignal>
#include <string>
#include <iostream>
bool abort_ = false;
void SigIntHandler(int signum) {
std::cout << "Received SIGINT" << std::endl;
abort_ = true;
}
int main(int argc, char *argv[]) {
signal(SIGINT, SigIntHandler);
while (!abort_) {
std::string line;
std::cout << "> ";
std::getline(std::cin, line);
if (!std::cin)
std::cin.clear();
std::cout << line << std::endl;
}
}
?或者还有其他方法可以从std::getline()
读取,这也是对信号的响应吗?
答案 0 :(得分:1)
std::getline
和输入/输出库通常在进程收到信号时没有指定的行为。 C ++库和语言未指定任何特定行为。信号只是顺便提一下,最值得注意的参考只是:
对函数信号的调用与任何结果同步 调用如此安装的信号处理程序。
这和头文件的枚举是C ++库中信号引用的总和。信号是一种高度运行的特定于系统的功能,C ++库根本不包含这些功能。
这里讨论的C ++库函数和类都不是信号安全的。在显示的代码中,信号处理程序不能对输入流做任何事情,因为它的内部状态是不确定的,整个事情不是信号安全的。
因此,要处理信号,有必要采用低级操作系统特定的调用,例如open()
,read()
和write()
,而不是使用C ++输入/输出库。当然,其中一个选项是编写自己的std::streambuf
子类,使用低级系统调用实现其功能,并适当地处理信号。通过将流缓冲区设置为失败状态(或者,模拟接收ENTER
密钥,嘿,它是您的节目)并返回,您自己的实现将适当地阻止输入和处理任何接收到的信号。