这是this question的后续行动。我正在尝试确保多个线程按特定顺序更改公共资源(m_pCurrentWorker)。我在每个线程使用互斥和条件变量,并且在线程执行结束时,我通知下一个线程的条件变量以便继续。工作代码如下,我运行了几十次,总是得到正确的执行顺序,似乎没有死锁:
entered thread 0
leaving thread 0
entered thread 1
leaving thread 1
entered thread 2
leaving thread 2
然而,在原始问题下面讨论了这种实现是错误的。很高兴听到其他人对这个设计的看法以及改进它的建议。
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
std::mutex* m_pMutexs;
std::condition_variable* m_pCVs;
int m_pCurrentWorker;
void func(int i)
{
std::mutex* pCurMutex = &m_pMutexs[i];
std::condition_variable* pCuCV = &m_pCVs[i];
std::unique_lock<std::mutex> lk(m_pMutexs[i]);
while (i != m_pCurrentWorker)
{
pCuCV->wait(lk);
}
std::cout << "entered thread " << i << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(rand() % 2));
std::cout << "leaving thread " << i << std::endl;
m_pCurrentWorker++;
lk.unlock();
if (m_pCurrentWorker > 2)
{
return;
}
pCuCV = &m_pCVs[m_pCurrentWorker];
pCuCV->notify_one();
}
int _tmain(int argc, _TCHAR* argv[])
{
m_pMutexs = new std::mutex[3];
m_pCVs = new std::condition_variable[3];
m_pCurrentWorker = 0;
srand((unsigned int)time(0));
std::thread t1(func, 0);
std::thread t2(func, 1);
std::thread t3(func, 2);
t1.join();
t2.join();
t3.join();
return 0;
}