在C ++中中断getLine()while循环

时间:2014-11-23 11:10:29

标签: c++ multithreading while-loop getline

我制作了一个控制台应用程序,它接受来自两个来源的命令:

  1. 实际的控制台 - >这是一个单独的线程中的while(getLine())循环。
  2. websocket服务器 - >这也是在单独的线程上运行
  3. 如果输入了命令,则该命令将存储在向量中,直到另一个while循环(每20ms运行一次)循环通过在所通过的时间内输入的所有命令。如果他读了一个命令,他就会执行它。

    现在,有一个Stop命令可以停止应用程序。输入后,应用程序将按预期关闭。但问题是:这需要一些时间,您仍然可以从第一个命令源(getline())输入文本。键入内容后,关闭序列将停止,并等待您按Enter键。

    一旦关闭序列开始,我终止第一个线程(包含getline循环)。但这不起作用......

    有什么想法吗?

    提前致谢!

2 个答案:

答案 0 :(得分:0)

getline()是一个阻塞调用,如果你想从其他线程接收消息(即关闭命令),你可能不得不使用不同的东西。您没有提到您用于多线程的库以及如何终止控制台读取线程(可能,您停止线程的方式仍然不会强制它退出getline

这个问题似乎有一些相关的答案:Peek stdin using pthreads

顺便说一句,你提到了一个向量,它是从多个线程访问的(如果我理解的话)。您必须注意正确的同步(例如,在访问向量时使用互斥锁)。

此外,您有某种循环,每20毫秒“轮询”一次向量,这表明您的应用程序整体设计可能存在一些缺陷。尝试通过使用更合适的方法在线程之间传递事件来消除它,例如条件变量。

答案 1 :(得分:0)

问题在于getline是一个阻止呼叫,在标准输入的情况下,按Enter键后将返回。

我有一个类似的问题,如下所示解决了。 我使用了两个文件描述符:一个用于监视标准输入,另一个用于监视“自管道”。万一发生某些事件,后者会触发解锁select。前者确保getline一旦可以读取整行就被调用。

#include <future>
#include <string>
#include <iostream>
#include <thread>
#include <unistd.h>
#include <stdio.h>
#include <sys/select.h>

int pipe_fd[2];
auto p = pipe(pipe_fd);
auto stdin_fd = fileno(stdin); // 0

fd_set check_fd;


int main(int argc, char const *argv[])
{
    FD_ZERO(&check_fd);
    FD_SET(stdin_fd, &check_fd);
    FD_SET(pipe_fd[0], &check_fd);

    auto t1 = std::async(std::launch::async, [] {
        std::this_thread::sleep_for(std::chrono::seconds(10));
        uint32_t dummy = 43;
        // this will stop the data input
        write(pipe_fd[1], &dummy, sizeof(dummy));
    });

    auto maxfd = pipe_fd[0] > pipe_fd[1] ? pipe_fd[0] : pipe_fd[1];
    select(maxfd + 1, &check_fd, nullptr, nullptr, nullptr);
    if (FD_ISSET(stdin_fd, &check_fd))
    {
        std::string input;
        std::getline(std::cin, input);
        std::cout << "You enterd:" << input << std::endl;
    }

    if (FD_ISSET(pipe_fd[0], &check_fd))
        std::cout << "Event" << std::endl;

    return 0;
}