简体   繁体   English

通过信号唤醒 std::getline

[英]Wake up std::getline through signal

I read user input from stdin via std::getline() , and I want to be able to exit the program by SIGINT.我通过std::getline()stdin读取用户输入,并且我希望能够通过 SIGINT 退出程序。 Unfortunately, std::getline() does not seem to wake up on any signal.不幸的是, std::getline()似乎没有在任何信号上醒来。 Hence, the code below only aborts after pressing CTRL-C and RETURN.因此,下面的代码只会在按下 CTRL-CRETURN 后中止。

#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;
  }
}

Why is that so?为什么会这样? Do I have any chance to wake up std::getline() except by user input?除了用户输入,我还有机会唤醒std::getline()吗? Or is there any other way to read from stdin , that is also responsive to signals?或者有没有其他方法可以从stdin读取,也可以响应信号?

std::getline , and the input/output library in general, does not have a specified behavior when the process receives a signal. std::getline以及一般的输入/输出库在进程接收信号时没有指定的行为。 The C++ library, and language, does not specify any particular behavior. C++ 库和语言没有指定任何特定的行为。 Signals are only briefly mentioned in passing, with the most notable reference being only that:信号只是顺便提及,最显着的参考仅是:

A call to the function signal synchronizes with any resulting invocation of the signal handler so installed.对函数信号的调用与如此安装的信号处理程序的任何结果调用同步。

That, and the enumeration of the header file, is the sum total of references to signals in the C++ library.那和头文件的枚举是对 C++ 库中信号引用的总和。 Signals are a highly operating system-specific feature, that's simply not covered by the C++ library.信号是一个高度特定于操作系统的功能,C++ 库根本没有涵盖它。

None of the C++ library functions and classes discussed here are signal-safe.此处讨论的 C++ 库函数和类都不是信号安全的。 In the shown code, the signal handler cannot do anything to the input stream, because its internal state is indeterminate, and the whole thing is not signal-safe.在显示的代码中,信号处理程序不能对输入流做任何事情,因为它的内部状态是不确定的,而且整个事情不是信号安全的。

As such, to deal with signals it will be necessary to resort to low level operating system-specific calls, like open() , read() , and write() , instead of using the C++ input/output library.因此,为了处理信号,有必要求助于低级操作系统特定的调用,如open()read()write() ,而不是使用 C++ 输入/输出库。 Of course, one of the options is write your own subclass of std::streambuf , implementing its functionality using low level system calls, and handling signals appropriately.当然,选项之一是编写自己的std::streambuf子类,使用低级系统调用实现其功能,并适当处理信号。 Your own implementation will be appropriately blocking on input and handling any received signal by setting the stream buffer to failed state (or, perhaps, simulating receiving an ENTER key, hey, it's your show) and returning.您自己的实现将通过将流缓冲区设置为失败状态(或者,可能模拟接收ENTER键,嘿,这是您的节目)并返回来适当地阻止输入并处理任何接收到的信号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM