Do I Need to Protect Read Access to an Stl Container in a Multithreading Environment

Do I need to protect read access to an STL container in a multithreading environment?

Yes, the read threads will need some sort of mutex control, otherwise the write will change things from under it.

A reader/writer mutex should be enough. But strictly speaking this is an implmentation-specific issue. It's possible that an implementation may have mutable members even in const objects that are read-only in your code.

do I need to protect access to different keys in a std::list (multi-threading) C++

In general any sort of modifications to any of the std containers should absolutely be protected.

You could consider using a pthread_rwlock, using a read lock for reading and a write lock for writing. The nice thing about rwlocks is that you can have multiple simultaneous readers, thus reducing locking contention. Or at the very least a pthread_mutex. (Assuming Linux, of course)

Multithreading: do I need protect my variable in read-only method?

Yes, unless you can guarantee that changes to the underlying variable counter are atomic, you need the mutex.

Classic example, say counter is a two-byte value that's incremented in (non-atomic) stages:

(a) add 1 to lower byte
if lower byte is 0:
(b) add 1 to upper byte

and the initial value is 255.

If another thread comes in anywhere between the lower byte change a and the upper byte change b, it will read 0 rather than the correct 255 (pre-increment) or 256 (post-increment).

In terms of what data types are atomic, the latest C++ standard defines them in the <atomic> header.

If you don't have C++11 capabilities, then it's down to the implementation what types are atomic.

Are std::map and std::set thread-safe?

The C++ standard says nothing about this.1 You will have to look at the documentation for the particular implementation of the standard library that you're using. But it's quite likely that it won't be thread-safe, so you will need to do synchronisation yourself.

(If you want to know how to do that, well, that's a different question topic...)


1. Pre-C11.

Thread safety of std:map and std:set

Race conditions will happen: depending on the CPU's ordering of the things done, you will receive different results each time. If an iterator is invalidated (by e.g. deleting an item in one thread and the other thread has an iterator pointing to that now invalid memory) and then used in the other thread, you will get undefined behavior, so be wary of dead babies, clay golems, and haunts, along with the more likely segfaults, delayed segfaults, and runtime crashes.

C++11 introduces mutex and other threading facilities: guard your reads and writes with those if you must.



Related Topics



Leave a reply



Submit