条件变量只发出变化信号,它们本身并不是很有用。你需要把它和一个状态结合起来。
添加另一个变量,它决定了它的转向。
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