Search code examples
c++multithreadingthread-safetyopenmp

Is the vector reference operator[] threadsafe for writing?


Let's say I have the following code snippet.

// Some function decleration
void generateOutput(const MyObj1& in, MyObj2& out);

void doTask(const std::vector<MyObj1>& input, std::vector<MyObj2>& output) {

    output.resize(input.size());

    // Use OpenMP to run in parallel

#pragma omp parallel for
    for (size_t i = 0; i < input.size(); ++i) {
        generateOutput(input[i], output[i]);
    }

}

Is the above threasafe? I am mainly concerned about writing to output[i]. Do I need some sort of locking? Or is it unnecessary? ex:


// Some function prototype
void generateOutput(const MyObj1& in, MyObj2& out);

void doTask(const std::vector<MyObj1>& input, std::vector<MyObj2>& output) {

    output.resize(input.size());

    // Use OpenMP to run in parallel

#pragma omp parallel for
    for (size_t i = 0; i < input.size(); ++i) {
        MyObj2 tmpOutput;
        generateOutput(input[i], tmpOutput);
#pragma omp critical
        output[i] = std::move(tmpOutput);
    }

}

I am not worried about the reading portion. As mention in this answer, it looks like reading input[i] is threadsafe.


Solution

  • output[i] does not write to output. This is just a call to std::vector<MyObj2>::operator[]. It returns an unnamed MyObj2&, which is then used to call generateOutput. The latter is where the write happens.

    I'll assume that generateOutput is threadsafe itself, and MyObj2 too, since we don't have code for that. So the write to MyObj2& inside generateOutput is also threadsafe.

    As a result, all parts are threadsafe.