C++: Control order of thread execution with mutex's and conditional variables

一笑奈何 提交于 2020-01-05 23:26:53

问题


This question is a follow up for this question. I want threads to perform some work and pass handle to the next thread in order. When trying to execute the following code, I get

Unhandled exception at 0x0F7C1F5F (msvcp120d.dll) in ConsoleApplication9.exe: 0xC0000005 : Access violation reading location 0x00000004.

    #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)
    {
        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<std::mutex> 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() << std::endl;

        m_pCurrentWorker++;
        lk.unlock();
        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;
    }

回答1:


Have no idea what you're trying to do but

You're casting integer to pointer?

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

I think you should write instead:

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

The whole function could be something like this:

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 " << 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();

}



回答2:


I did some further research and it seems that the code the original questions is not thread-safe



来源:https://stackoverflow.com/questions/32535394/c-control-order-of-thread-execution-with-mutexs-and-conditional-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!