问题
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);
}
回答1:
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.
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();
}
来源:https://stackoverflow.com/questions/42395777/how-to-stop-from-another-thread-stdcin-from-reading-anymore-input