2009-06-23 5 views
1

이 코드는 생산자의 void push(data) 내부 뮤텍스에서 대기 할 것인가?이 부스트 조건 코드 사용에 문제가 있습니까?

그렇다면 어떻게 해결할 수 있습니까?

boost::mutex access; 
boost::condition cond; 

// consumer 
data read() 
{ 
    boost::mutex::scoped_lock lock(access); 

    // this blocks until the data is ready 
    cond.wait(lock); 

    // queue is ready 
    return data_from_queue(); 
} 

// producer 
void push(data) 
{ 
    //<--- will a block ever happen here? 
    boost::mutex::scoped_lock lock(access); 
    // add data to queue 

    cond.notify_one(); 
} 

((;;) 루프에 대한 스레드 풀이 있고이 풀의 스레드에서 read() 호출이 있다고 가정 해 봅시다. 그런 다음 데이터를 처리합니다. 그리고 push()를 외부 스레드로 호출합니다. 내 질문은, 그 외부 스레드도 (데이터) 푸시에 대한 호출에 차단할 수 있습니까?

답변

0

.wait()이 호출되면 스레드 풀의 호출 스레드를 차단하고 뮤텍스를 릴리스합니다. 누군가 notify_one() 또는 notify_all()을 호출하면 리턴됩니다. 차단 된 스레드가 반환되기 전에 mutex를 다시 획득하고 스레드 풀의 스레드를 차단 해제합니다.

따라서 외부 스레드가 void push(data)을 호출하면 .wait()가 호출 될 때까지 일시적으로 차단됩니다.

boost documentation on the condition's wait function을 참조하십시오.

+2

사실이 아닙니다. void 푸시 (데이터)는 대기가 호출 될 때까지 차단되지 않습니다. 뮤텍스를 얻을 수없는 경우에만 차단되며, 다른 누군가가 뮤텍스를 해제 할 때까지 기다려야합니다. 데이터 read() 함수는 실제로 대기열에 항목이 있는지 확인해야합니다 (대기 (wait)를 호출하지 않았거나 가짜 깨우기가 발생했을 때 항목이 추가되었을 수 있습니다). 함수는 "while (queue is empty) cond.wait (lock); return data_from_queue();"를 수행해야합니다. – nos

8

waitnotify없이 호출 할 수 있습니다. 이를 spurious wakeup이라고합니다. 이를 처리하기 위해 조건을 사용하는 코드는 예상 조건이 실제로 적용되는지 확인하는 wait 주위의 루프를 항상 가져야합니다. 예 :

queue data_queue; 
boost::mutex access; 
boost::condition cond; 

// consumer 
data read() 
{ 
    boost::mutex::scoped_lock lock(access); 

    while (queue.is_empty()) { 
    // this blocks until the data is ready 
    cond.wait(lock); 
    } 

    // queue is ready 
    return data_from_queue(); 
} 

// producer 
void push(data) 
{ 
    boost::mutex::scoped_lock lock(access); 

    // add data to queue 
    queue.push_back(data); 

    cond.notify_one(); 
} 

개념적으로 "조건"은 오해의 소지가 있습니다. 대신 당신은 그것을 신호로 생각할 수 있습니다. 일어나기 위해 다른 스레드 또는 스레드에 신호를 보내고 있지만 약속하지는 않습니다. "어이, 어쩌면 데이터가 준비되어있어 어쩌면 체크하지 그래?"

+0

((;;) 루프에 대한 스레드 풀이 있고이 풀의 스레드에서 read() 호출이 있다고 가정 해 봅니다. 그런 다음 데이터를 처리합니다. 그리고 push()를 외부 스레드로 호출합니다. 내 질문은, 그 외부 스레드도 (데이터) 푸시에 대한 호출에 차단할 수 있습니까? –

+0

예를 들어 큐가 비어 있다고 가정합니다 ( –

+0

) read 뮤텍스가 read()에서 반환되기 전까지 보유되지 않습니까? –

관련 문제