2017-02-22 119 views
0

我啓動了兩個線程,thread t1正在等待通過cin輸入。我可以把類似EOF位的東西從thread t2cin停止cin從閱讀?我試過'\n'ios::eofbit。兩者都不起作用。如何從另一個線程停止std :: cin從讀取輸入?

#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); 
} 
+0

@KerrekSB沒有cin.close()函數...請糾正我,如果我錯了 – Mario

+0

你是對的,永遠牢記:-S –

+0

@Mario嘗試'::接近(STDIN_FILENO) ;'或':: fclose(stdin);'或甚至':: close(0);'。看到http://stackoverflow.com/questions/288062/is-close-fclose-on-stdin-guaranteed-to-be-correct這有點激烈...... –

回答

0

我不認爲有一個標準的非阻塞讀取istream或一種方法來中斷等待輸入的線程。你可以試着看看boost asio或者提升iostreams - 也許他們有這個功能。

您可以在POSIX系統或其他系統上的對應選項上使用select/poll來檢查是否有數據可用,或使用某種形式的中斷讀取 - API也取決於系統。

下面是一個骯髒的解決方案 - 最終會有一個泄露的線程,將永遠等待stdin,但它做到了你想要的。

#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(); 
} 
相關問題