條件變量只發出變化信號,它們本身並不是很有用。你需要把它和一個狀態結合起來。
添加另一個變量,它決定了它的轉向。
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...)
你忘了實際的溝通!你有一個互斥體,但它不能保護任何東西! – 2014-12-05 07:58:33