如何停止从另一个线程std :: cin读取更多输入? [英] How to stop, from another thread, std::cin from reading anymore input?

查看:143
本文介绍了如何停止从另一个线程std :: cin读取更多输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我启动了两个线程,线程t1 正在等待通过 cin 的输入。我可以把 EOF 放在 thread t2 停止阅读 cin ?我尝试了’\n’ ios :: eofbit 。两者均无效。

I started two threads, thread t1 is waiting for input via cin. Can I put something like an EOF bit to cin from thread t2to stop cin from reading? I tried '\n' and ios::eofbit. Both did not work.

#include <thread>
#include <iostream>
#include <string>
#include <condition_variable>

std::condition_variable cv;

void Foo()
{
    std::string sFoo;
    std::cin >> sFoo;
    // Do stuff with sFoo
}

void Bar()
{
    // Do stuff
    // If a condition is fullfilled I don't need the input in Foo anymore and so I want to cancel cin.

    std::cin.setstate(std::ios::setstate(std::ios::eofbit); // Does not work
    std::cin.putback('\n'); // Does not work

    // maybe something similar like these above
}

int main()
{
    std::thread t1(Foo);
    std::thread t2(Bar);
}


推荐答案

我认为从istream中没有标准的非阻塞读取,也没有中断线程等待输入的方法,您可以尝试看看boost asio或boost iostreams-也许它们具有此功能。

I don't think there is a standard non-blocking read from istream or a means to interrupt a thread waiting for input. You might try to look at boost asio or boost iostreams - perhaps they have this functionality.

您可以在POSIX系统或其他系统上使用select / poll来检查是否有可用数据,或使用某种形式的中断读取-API也是依赖于系统的。

You could use select/poll on POSIX systems or their counterparts on other systems to check if any data is available, or use some form of interruptive read - API is system-dependent also.

下面是一个行之有效的肮脏解决方案-您最终会发现一个泄漏的线程,它将永远等待

Below is a dirty solution that works - you end up with a leaked thread that will forever wait on stdin, but it does what you want.

#include <thread>
#include <iostream>
#include <string>
#include <condition_variable>
#include <chrono>
#include <mutex>
#include <queue>

std::mutex m;
bool dataEnd = false;
std::queue<std::string> data;
std::condition_variable sAvail;

void Reader() {
    while (std::cin) {
        auto s = std::string();
        std::cin >> s;

        auto lock = std::unique_lock<std::mutex>(m);
        data.push(std::move(s));
        sAvail.notify_all();
    }
}

void Foo() {
    for (;;) {
        auto lock = std::unique_lock<std::mutex>(m);
        if (data.empty()) {
            sAvail.wait(lock);
            if (dataEnd) {
                std::cerr << "No more data!\n";
                break;
            }
        }

        if (!data.empty()) {
            auto s = std::move(data.front());
            data.pop();
            std::cerr << "Got " << s << '\n';
        }
    }
}

void Bar(std::thread& reader) {
    // Do stuff
    // If a condition is fullfilled I don't need the input in Foo anymore and so I want to cancel cin.

    {
        auto lock = std::unique_lock<std::mutex>(m);
        dataEnd = true;
        sAvail.notify_all();
        reader.detach();
    }

    // maybe something similar like these above
}

int main() {
    std::thread r(Reader);
    std::thread t1(Foo);
    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    std::thread t2(Bar, std::ref(r));

    t1.join();
    t2.join();
}

这篇关于如何停止从另一个线程std :: cin读取更多输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆