What does the C++ standard library guarantee to avoid data races?

Viewed 145

Reading C++11 FAQ -- Threads there's this paragraph which I don't understand:

Consequently, C++11 provides some rules/guarantees for the programmer to avoid data races:

  • A C++ standard library function shall not directly or indirectly access objects accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's arguments, including this.
  • A C++ standard library function shall not directly or indirectly modify objects accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's nonconst arguments, including this.
  • C++ standard library implementations are required to avoid data races when different elements in the same sequence are modified concurrently.

I know what a data race is, and multithreading generally, but I don't understand what these sentences are saying.

Could you explain them more clearly? Perhaps with an example? What is or isn't it safe for me (i.e. an application programmer) to do in a multi-threaded context?

Had I not read these, I would have guessed that it's not safe to have multiple threads calling a non-const method of an object of any type, but I suppose this is saying something in addition to that?

1 Answers

OK I think I figured it out from the comments (please correct me if I'm wrong).

  • These first two are similar -- i.e. that a function will only read or write memory that's reachable via the function argument.

    Perhaps this means, no more and no less than, that functions won't read or mutate global or static data in their implementation.

    There were a few functions in the C library which broke this rule, for example ctime.

    ctime returns a pointer to static data and is not thread-safe.

  • The third is saying that a thread can mutate an element in a container while another thread accesses a different element.

    This does not imply that it's also inherently safe to mutate the container, e.g. to insert a new element.

    And vector<bool> is an exception to this rule:

    std::vector<bool> behaves similarly to std::vector, but in order to be space efficient, it ... does not guarantee that different elements in the same container can be modified concurrently by different threads.

Related