C ++: Ordre de contrôle de l’exécution du thread avec les variables mutex et conditionnelles

Cette question fait suite à cette question . Je veux que les threads effectuent du travail et passent le handle du prochain thread dans l’ordre. En essayant d’exécuter le code suivant, j’obtiens

Exception non gérée à 0x0F7C1F5F (msvcp120d.dll) dans ConsoleApplication9.exe: 0xC0000005: emplacement de lecture des violations d’access 0x00000004.

#include "stdafx.h" #include  #include  #include  #include  #include  std::mutex* m_pMutexs; std::condition_variable* m_pCVs; int m_pCurrentWorker; void func(int i) { int cvCurrentInd = i; std::mutex* pCurMutex = &m_pMutexs[cvCurrentInd]; std::condition_variable* pCuCV = (std::condition_variable*)(m_pCurrentWorker + i*sizeof(std::condition_variable)); std::unique_lock lk(m_pMutexs[i]); while (i != m_pCurrentWorker) { pCuCV->wait(lk); } std::cout << "entered thread " << std::this_thread::get_id() << std::endl; std::this_thread::sleep_for(std::chrono::seconds(rand() % 10)); std::cout << "leaving thread " << std::this_thread::get_id() <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; } 

Je n’ai aucune idée de ce que vous essayez de faire mais

Vous lancez un entier sur un pointeur?

 std::condition_variable* pCuCV = (std::condition_variable*)(m_pCurrentWorker + i*sizeof(std::condition_variable)); 

Je pense que vous devriez écrire à la place:

 std::condition_variable* pCuCV = &m_pCVs[i]; 

La fonction entière pourrait être quelque chose comme ceci:

 void func(int i) { std::mutex* pCurMutex = &m_pMutexs[i]; std::condition_variable* pCuCV = &m_pCVs[i]; std::unique_lock lk(m_pMutexs[i]); while (i != m_pCurrentWorker) { pCuCV->wait(lk); } std::cout << "entered thread " << std::this_thread::get_id() << std::endl; std::this_thread::sleep_for(std::chrono::seconds(rand() % 2)); std::cout << "leaving thread " << std::this_thread::get_id() << std::endl; m_pCurrentWorker++; lk.unlock(); if (m_pCurrentWorker > 2) { return; } pCuCV = &m_pCVs[m_pCurrentWorker]; pCuCV->notify_one(); } 

J’ai fait des recherches plus poussées et il semble que le code des questions originales ne soit pas thread-safe