2016-09-23 4 views
3

이것은 무한 루프를 사용하여 무언가를 입력하고 대기열에 저장하기를 기다리는 함수 start()가있는 간단한 프로그램입니다. start()는 별도의 스레드에서 실행됩니다. 사용자가 몇 가지 값을 입력하면 대기열의 크기는 메인에서 0으로 유지됩니다. 대기열은 어떻게 동기화 될 수 있습니까?
코드 : source.cpp는
두 스레드 간의 큐 동기화

#include <iostream> 
#include "kl.h" 

using namespace std; 

int main() 
{ 
    std::thread t1(start); 
    while (1) 
    { 
     if (q.size() > 0) 
     { 
      std::cout << "never gets inside this if\n"; 
      std::string first = q.front(); 
      q.pop(); 
     }   
    } 
    t1.join(); 
} 

코드 : kl.h는

#include <queue> 
#include <iostream> 
#include <string> 

void start(); 
static std::queue<std::string> q; 

코드 : kl.cpp는

#include "kl.h" 
using namespace std; 

void start() 
{ 
    char i; 
    string str; 
    while (1) 
    { 
     for (i = 0; i <= 1000; i++) 
     { 
      //other stuff and str input 
      q.push(str); 
     } 

    } 
} 
+0

추가 전체 코드 – user6275035

+0

당신이 헤더 파일의 큐에 '정적'을 사용하기 때문에, 당신은 실제로 2 개의 다른 큐, 각각의 CPP의 하나가 파일. 그것이 메인에있는 것이 항상 비어있는 이유입니다. – tony

+0

@tony 정적 제거시 링커 오류를 보여줍니다. – user6275035

답변

2

귀하의 코드는 race 포함 - 나 그것에 의해 추락했다; 두 스레드가 잠재적으로 공유 대기 행렬을 수정합니다. (또한, 아마도 char i 값으로 최대 1000의 값을 반복하고 있습니다.)

공유 대기열을 std::mutex으로 보호하고 std::condition_variable을 사용하여 확인해야하는 이유를 알리십시오 대기열.

  1. 액세스 뮤텍스를 유지에만 큐 :

    특히, (a producer consumer의 사건에 대한 매우 일반적인) 다음 사항을 고려해야합니다.

  2. 조건 변수를 사용하여 무언가를 푸시했음을 알립니다.

  3. 조건 변수를 사용하여 처리를 계속할 지점이있을 때 조건을 지정하십시오. 여기

는 코드의 재 작성 :

#include <iostream> 
#include <queue> 
#include <thread> 
#include <condition_variable> 
#include <mutex> 

using namespace std; 

std::queue<std::string> q; 
std::mutex m; 
std::condition_variable cv; 

void start() 
{ 
    string str; 
    for (std::size_t i = 0; i <= 1000; i++) { 
     //other stuff and str input 
     std::cout << "here" << std::endl; 
     std::unique_lock<std::mutex> lk(m); 
     q.push(str); 
     lk.unlock(); 
     cv.notify_one(); 
    } 
} 

int main() 
{ 
    std::thread t1(start); 
    for (std::size_t i = 0; i <= 1000; i++) 
    { 
     std::unique_lock<std::mutex> lk(m); 
     cv.wait(lk, []{return !q.empty();}); 
     std::string first = q.front(); 
     q.pop();  
    } 
    t1.join(); 
}