2017-02-22 8 views
0

을 통해 thread t1이 입력을 기다리고있는 두 개의 스레드를 시작했습니다. EOF 비트를 cin에 넣고 thread t2에서 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

를 틀렸다면 정정 해줘 제발 당신 맞아요, 결코 마음 :'시도 @Mario –

+0

-S : 가까운 (STDIN_FILENO) ; 또는':: fclose (stdin);'또는':: close (0);'도 사용할 수 있습니다. http://stackoverflow.com/questions/288062/is-close-fclose-on-stdin-guaranteed-to-be-correct를 참조하십시오. 다소 과감한 내용입니다 ... –

답변

0

istream에서 표준 비 블로킹 읽기 또는 입력 대기중인 스레드를 인터럽트하는 수단이 없다고 생각합니다. boost asio를 보거나 iostream을 향상 시키려고 할 수도 있습니다. 아마도이 기능을 가지고있을 것입니다.

다른 시스템의 POSIX 시스템 또는 해당 시스템에서 select/poll을 사용하여 데이터가 사용 가능한지 확인하거나 일부 형식의 인터럽트 읽기를 사용할 수도 있습니다. API는 시스템 종속적입니다.

다음은 더러운 해결책입니다. 누출 된 스레드가 끝나면 영원히 표준 입력을 기다리지 만 원하는 것은 수행합니다.

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