Question

I'm trying to understand multi threading in C++. In the following bit of code, will the deque 'tempData' declared in retrieve() always have every element processed once and only once, or could there be multiple copies of tempData across multiple threads with stale data, causing some elements to be processed multiple times? I'm not sure if passing by reference actually causes there to be only one copy in this case?

static mutex m;

void AudioAnalyzer::analysisThread(deque<shared_ptr<AudioAnalysis>>& aq)
{

    while (true)
    {
        m.lock();
        if (aq.empty())
        {
            m.unlock();
            break;
        }
        auto aa = aq.front();
        aq.pop_front();
        m.unlock();

        if (false) //testing
        {
            retrieveFromDb(aa);
        }
        else
        {
            analyzeAudio(aa);
        }
    }
}

void AudioAnalyzer::retrieve()
{
    deque<shared_ptr<AudioAnalysis>>tempData(data);
    vector<future<void>> futures;
        for (int i = 0; i < NUM_THREADS; ++i)
    {
        futures.push_back(async(bind(&AudioAnalyzer::analysisThread, this, _1), ref(tempData)));
    }

    for (auto& f : futures)
    {
        f.get();
    }
}
Was it helpful?

Solution

Looks OK to me.

Threads have shared memory and if the reference to tempData turns up as a pointer in the thread then every thread sees exactly the same pointer value and the same single copy of tempData. [You can check that if you like with a bit of global code or some logging.]

Then the mutex ensures single-threaded access, at least in the threads.


One problem: somewhere there must be a push onto the deque, and that may need to be locked by the mutex as well. [Obviously the push_back onto the futures queue is just local.]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top