Tiki
Tiki

Reputation: 1178

Is is thread-safe to copy/modify a copy of an STL container?

I have a std::map that is going to be modified from multiple threads, and I have a mutex to lock these writes. However, the map must occasionally be used during a long-running operation, and it would not be good to hold the lock during this entire operation, blocking all of those writes.

I have two questions about this:

For example:

class Foo {
    void writeToMap(Bar &bar, Baz &baz) {
        // lock mutex
        map[bar] = baz;
        // unlock mutex
    }

    std::map<Bar, Baz> getMapCopy() {
        // lock mutex (Is this necessary?)
        std::map<Bar, Baz> copy (map);
        // unlock mutex
        return copy;
    }

    std::map<Bar, Baz> map;
};

void expensiveOperation(Foo &f) {
    std::map<Bar, Baz> mapCopy = f.getMapCopy();
    // Can I safely read mapCopy?
}

Upvotes: 0

Views: 641

Answers (2)

AlexK
AlexK

Reputation: 1281

Sounds like the copy operation itself is not thread safe, the issue being atomicity of copying 64-bit values. You copy the first 4 bytes, while the second 4 is being modified by another thread leaving you with inconsistent 8 bytes.

Please have a look here: Is copy thread-safe?

If you manage to create a consistent copy, however, I do not see why not...

Upvotes: 3

Some programmer dude
Some programmer dude

Reputation: 409482

You have undefined behavior in that code, as you return a reference to a local variable. This locla variable will be destructed once the function returns, and you now have a reference to a destructed object.

If you want to return a copy then you have to return by value, so it would be e.g.

std::map<Bar, Baz> getMapCopy() {
    return map;
}

And if you use the mutexes and locks from the C++11 standard thread library you don't need an explicit unlock, the mutex will be unlocked with the destruction of the lock.

Upvotes: 2

Related Questions