如何停止从另一个线程std :: cin读取更多输入? [英] How to stop, from another thread, std::cin from reading anymore input?
问题描述
我启动了两个线程,线程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 t2
to 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屋!