是否有可能设置的std :: CIN超时?是否有可能设置的std :: CIN超时?(Is it p

2019-05-12 05:23发布

是否有可能设置的std :: CIN超时? 例如,给std :: cin期间不会10秒接收任何数据 - 它抛出异常或返回错误。

编辑:

并且怎么样从计时器Boost library ? 据我所知,它是可移植的库。 是否有可能要问Boost库的计时器抛出预定时间段后异常? 我想这可以解决这个问题。

Answer 1:

这是不可能设定一个时间出来std::cin在便携式的方式。 诉诸于非便携技术的情况下,也并不完全是微不足道的这样做:你将需要更换std::cin的流缓冲区。

在UNIX系统上我将取代使用默认的流缓冲区std::cin由一个自定义的,它使用文件描述符0来读取输入。 要实际读取输入我会使用poll()来检测输入的存在,并设置超时此功能。 根据结果poll()我想无论是读可用的输入或失败。 为了可能与未转发到文件描述符键入的字符应付,但是,它可能是合理的,也关掉做,直到进入一个新行的缓冲。

当使用多个线程可以创建它使用上线程来读取实际的数据,而另一个线程来使用定时条件变量等待便携式滤波数据流缓存器或者用于所述第一线程发信号通知它接收到的数据或用于超时到期。 请注意,您需要防范虚假唤醒,以确保当没有输入超时确实达到了。 这将避免鼓捣与实际数据的方式读取std::cin尽管它仍然替换使用的流缓冲区std::cin ,使功能通过这个名字进行访问。



Answer 2:

我只是想出了如何做到这一点,轮询给std :: cin文件描述符。

如果发生超时,没有发生事件,1万一发生什么事,和poll函数返回0 -1,如果发生错误。

#include <iostream>

#include <signal.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>


bool stop = false;

void intHandler(int dummy)
{
    stop = true;
}

std::string readStdIn()
{
    struct pollfd pfd = { STDIN_FILENO, POLLIN, 0 };

    std::string line;
    int ret = 0;
    while(ret == 0)
    {
        ret = poll(&pfd, 1, 1000);  // timeout of 1000ms
        if(ret == 1) // there is something to read
        {
            std::getline(std::cin, line);
        }
        else if(ret == -1)
        {
            std::cout << "Error: " << strerror(errno) << std::endl;
        }
    }
    return line;
}

int main(int argc, char * argv[])
{
    signal(SIGINT, intHandler);
    signal(SIGKILL, intHandler);

    while(!stop)
    {
        std::string line = readStdIn();
        std::cout << "Read: " << line << std::endl;
    }
    std::cout << "gracefully shutdown" << std::endl;
}


文章来源: Is it possible to set timeout for std::cin?