質問

I read a lot of posts here with the question if the standard containers for C++ (like "list" or "map" are thread safe and all of them said that it is not in general. Parallel reads should be OK, but parallel writes or parallel reads and writes may cause problems.

Now I found out that at www.cplusplus.com that accessing or modifying the list during most of the operations is safe.

Some examples:

map::find

The container is accessed (neither the const nor the non-const versions modify the container). No mapped values are accessed: concurrently accessing or modifying elements is safe.

map::insert

The container is modified. Concurrently accessing existing elements is safe, although iterating ranges in the container is not.

Do I missunderstand cplusplus.com or is there anything else what I have to know about thread safety in std containers.

Thanks in advance!

PS: I'm asking for C++03 and not for C++11

役に立ちましたか?

解決 2

Sounds about right.

Note that accessing values within the map from multiple threads, if you modify the actual value, will also need to be protected. If you KNOW that two threads update DIFFERENT entries (I don't mean inserting/removing), then it's safe.

他のヒント

Parallel reads should be OK, but parallel writes or parallel reads and writes may cause problems.

That's correct. That is the guarantee offered in general for unsynchronised access to objects in C++. Such "problems" are formally called data races.

Now I found out that at www.cplusplus.com that accessing or modifying the list during most of the operations is safe.

No, containers don't offer more than the basic guarantee for concurrent reads. There will be a data race if one thread accesses it while another modifies it. However, with some containers, it's sometimes safe to access elements of the container while the container itself is modified.

The first example is saying that find does not modify the container or access element values (only keys), so is safe if other threads are accessing it, or modifying (different) values without modifying the container itself.

The second example is saying that you can safely access an existing element (using a reference or iterator to that element), since inserting an element will not interfere with the existing ones.

I'm asking for C++ and not for C++11

These days, C++ is C++11. If you're asking about historic versions of the language, they had nothing to say about threads, so the question is not answerable in general, only for a specific implementation and thread framework.

Before C++11, there was no notion of "thread" in the Standard. So, the question whether a container is thread-safe is meaningless in context of C++03.

As Marcin pointed out, C++03 doesn't have a notion of thread; hence, you can't assume any thread-safe operation even for concurrent reading in two threads after a write that is completely complete.

Think about this case: At t=0, you create a thread, let's call A At t=10 sec, thread B (which exists before thread A gets created) writes to a container. At t=1 hour, thread A and B both try to read the container without any synchronization through a 3rd party library (e.g. pthread).

C++03 only guarantees that thread B will see the correct value. But there is no guarantee that thread A will see the correct value because C++03 expects every program is single thread, and so C++03 specification can only guarantee the sequence of events being visible in the programmed order (as if in 1 thread).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top