조건 변수는 변경 사항을 알려주지 만 그 자체로는별로 유용하지 않습니다. 그것을 상태와 결합해야합니다.
누구의 차례인지 지시하는 또 다른 변수를 추가하십시오.
std::mutex m;
std::condition_variable cv;
int turn = 0;
void foo()
{
while(true)
{
std::unique_lock<std::mutex> ul(m);
if(turn == 1) {
// my turn
std::cout << "bar" << std::endl;
// tell them it's their turn
turn = 0;
cv.notify_one();
} else {
// not our turn, wait for a change.
cv.wait(ul);
}
}
}
int main()
{
std::thread t(foo);
while(true)
{
std::unique_lock<std::mutex> ul(m);
if(turn == 0) {
// my turn
std::cout << "foo" << std::endl;
// tell them it's their turn
turn = 1;
cv.notify_one();
} else {
// not our turn, wait for a change.
cv.wait(ul);
}
}
}
뮤텍스는 turn
변수에 대한 안전한 액세스를 위해 사용되며,이 변경된 때마다 다른 스레드가 일어나 새로운 값을 확인할 수 있도록, 당신은 조건 변수를 통지합니다.
편집 : 당신이 당신의 퍼즐을 해결하기 위해, 위의 내용을 이해 가정 : 즉
void foo()
{
std::unique_lock<std::mutex> ul(m);
while(true)
{
std::cout << "bar" << std::endl;
cv.notify_one();
cv.wait(ul);
}
}
int main()
{
std::unique_lock<std::mutex> ul(m);
std::thread t(foo);
while(true)
{
std::cout << "foo" << std::endl;
cv.notify_one();
cv.wait(ul);
}
}
을, 당신은 당신이 하위 스레드를 시작하기 전에, 루프의 외부에서 뮤텍스를 잠글 필요 , 차례가 가장 먼저 나오는 논리는 분명합니다. 그런 다음 작업을 수행하고 조건을 알린 다음 다른 스레드가 신호를 보내길 기다립니다. 논리의
흐름 :
Main Thread Sub Thread
------------------------------------------
Lock Mutex
Create Subthread
Try to lock mutex
but it is busy.
Print "foo" ...waiting for mutex...
Notify cvar ignores notification,
(still waiting for mutex)
Wait on cvar Obtains lock
(when waiting on a cvar, the lock is released.)
...waiting... Prints "bar"
Notified, but the Notify cvar
mutex is still locked
so we are waiting.
Obtains lock again Wait on cvar
Print "foo" ...waiting...
(etc...)
당신은 실제 통신을 잊었다! 뮤텍스가 있지만 아무것도 보호하지 않습니다! –