C++11 Thread safety of Random number generators

The C++11 standard library is broadly thread safe. The thread safety guarantees on PRNG objects are the same as on containers. More specifically, since the PRNG classes are all pseudo-random, i.e. they generate a deterministic sequence based on a definite current state, there is really no room to be peeking or poking at anything outside the contained state (which is also visible to the user).

Just as containers need locks to make them safe to share, you would have to lock the PRNG object. This would make it slow and nondeterministic. One object per thread would be better.

§17.6.5.9 [res.on.data.races]:

1 This section specifies requirements that implementations shall meet
to prevent data races (1.10). Every standard library function shall
meet each requirement unless otherwise specified. Implementations may
prevent data races in cases other than those specified below.

2 A C++ standard library function shall not directly or indirectly
access objects (1.10) accessible by threads other than the current
thread unless the objects are accessed directly or indirectly via the
function’s argu- ments, including this.

3 A C++ standard library function shall not directly or indirectly
modify objects (1.10) accessible by threads other than the current
thread unless the objects are accessed directly or indirectly via the
function’s non- const arguments, including this.

4 [ Note: This means, for example, that implementations can’t use a
static object for internal purposes without synchronization because it
could cause a data race even in programs that do not explicitly share
objects betweenthreads. —endnote]

5 A C++ standard library function shall not access objects indirectly
accessible via its arguments or via elements of its container
arguments except by invoking functions required by its specification
on those container elements.

6 Operations on iterators obtained by calling a standard library
container or string member function may access the underlying
container, but shall not modify it. [Note: In particular, container
operations that invalidate iterators conflict with operations on
iterators associated with that container. — end note ]

7 Implementations may share their own internal objects between threads
if the objects are not visible to users and are protected against data
races.

8 Unless otherwise specified, C++ standard library functions shall
perform all operations solely within the current thread if those
operations have effects that are visible (1.10) to users.

9 [ Note: This allows implementations to parallelize operations if
there are no visible side effects. — end note ]

Leave a Comment