2017-11-23 3 views
0

이것은 다중 스레드 프로그래밍 측면에서 기본적인 질문 일 수 있지만 모든 동시 데이터 구조없이 다음을 수행하고자합니다. 스택의 상단을 인쇄 출력은 다음과 같이보고되도록 튀어 나오게 각 스레드std :: stack을 동시에 처리하는 올바른 방법

class A 
{ 
    std::stack<int> s; 
public: 
    A() 
    { 
     s.push(7); s.push(6); s.push(5); s.push(4); s.push(3); s.push(2); s.push(1); 
    } 
    void process(int tid) 
    { 
     while (!s.empty()) 
     { 
      std::unique_lock<std::mutex> lck(m); 
      std::cout << tid << " --> " << s.top() << '\n'; 
      cv.wait(lck); 
      s.pop(); 
      cv.notify_all(); 
      lck.unlock(); 
     } 
    } 
    std::mutex m; 
    std::condition_variable cv; 
}; 

int main() 
{ 
    A a; 
    std::thread t1(&A::process, &a, 1); 
    std::thread t2(&A::process, &a, 2);  
    t1.join(); 
    t2.join(); 
} 

내가 원하는 :

1 --> 1 
2 --> 2 
1 --> 3 
2 --> 4 
... 

그래서 단 1 스레드가 입력해야 코드를 살펴 보자 while 본문을 실행하고 하나의 반복 만 실행하십시오.

는하지만 그 대신 항상 출력 :

1 --> 1 
2 --> 1 

다음은 무한히 나는이 어떻게 할 수있는

대기?

현재 솔루션에 어떤 문제가 있습니까?

+0

이것이 유일한 문제인지는 모르겠지만 절대로 루프 나 람다없이 조건 변수를 기다려서는 안됩니다. 아, 조건 변수가 일종의 세마포어라고 생각하는 것 같습니다. 또는 somesuch. – Yakk

+0

@ Yakk 나는 약간의 동기화를 제공하기 위해 조건부 변수를 사용하려고 생각했다. 따라서 루프의 1 반복 만 스레드에 의해 실행된다. – ampawd

답변

1

가짜 웨이크 업을 테스트하지 않고 조건 변수에 절대로 wait을 수행하지 마십시오. 가장 쉬운 방법은 lambda verson을 사용하는 것입니다.

condition_variable은 세마포어가 아니기 때문에 하위 레벨입니다.

class A 
{ 
public: 
    A() 
    { 
    s.push(7); s.push(6); s.push(5); s.push(4); s.push(3); s.push(2); s.push(1); 
    } 
    void process(int tid) 
    { 
    while (true) 
    { 
     std::unique_lock<std::mutex> lck(m); 
     cv.wait(lck, [&]{ return std::this_thread::get_id() != last || s.empty(); }); 
     // must only read within lock: 
     if (s.empty()) { 
     last = std::thread::id{}; // thread ids can be reused 
     break; 
     } 
     last = std::this_thread::get_id(); 
     std::cout << tid << " --> " << s.top() << '\n'; 
     s.pop(); 
     cv.notify_one(); 
    } 
    } 
    std::mutex m; 
    std::condition_variable cv; 
    std::thread::id last{}; 
    std::stack<int> s; 
}; 
+0

예. 이해하고 있지만 어쨌든 올바른 방식으로 작동하지 않는다. 빈 컨테이너에서 튀어 나오려고 예외를 던졌습니다 ... – ampawd

+0

@ampawd 고정 생각합니다. – Yakk

관련 문제