1

In C++11, is the algorithm std::random_shuffle thread safe (when called by two different threads on two different containers) ?

And particularly this form:

template <class RandomIt> void random_shuffle(RandomIt first, RandomIt last);
Vincent
  • 57,703
  • 61
  • 205
  • 388
  • 2
    Most likely not: that overload of `std::random_shuffle` probably calls `std::rand()`, which probably uses some global resource. – juanchopanza Jul 18 '13 at 10:21

2 Answers2

6

A function is threadsafe if two concurrent executions of that function do not "work" on the same data. "work" here means that none of the functions may modify the data in a non-atomic, non-consistent way. There are three ways how data can be accessed by the function:

  1. via function parameters, including objects referred to by those parameters
  2. via the objects a member function is called on
  3. Function static, class static and global data, including data used by functions that get called indirectly.

Since random_shuffle is a free function, 2. does not apply. The function however has parameters, and it works on them in the sense that it alters the underlying sequence's content. But there will be no problem if concurrent calls do not operate on overlapping sequences.

That leaves the static/global data. Most randum number generators will use some kind of global data for their seed. The default random function rand is not required to be threadsafe and probably will not explicitly synchronize access to its global seed.

So in your case no, it's not threadsafe (unless the random number generator is).

You will want to either write a synchronized version of random number generator ore use different generators in concurrent calls. I'd prefer to use the latter, so the concurrent shuffles dont interfere with the random number sequence of each other. (But I am by no means an expert in random number generation).

Arne Mertz
  • 24,171
  • 3
  • 51
  • 90
  • `rqnd` is not **required** to be thread-safe. That's not the same as saying that it's **not** thread-safe. Any particular implementation **can** make it thread-safe, and its documentation should tell you that. – Pete Becker Jul 18 '13 at 15:06
  • @PeteBecker *not required to be* means not threadsafe in standard C++. If a specific implementation provides more guarantees than the standard demands, that is an expansion to the standard. The answer is for the general language question, not for a specific implementation. Adding a "things might be better on your specific compiler" is unnecessary because it applies to almost every corner to the language, since the standard explicitly allows expansions. But I'll change the wording about `rand` a bit :-) – Arne Mertz Jul 19 '13 at 05:54
3

It is thread-safe if it uses a thread-safe random number generator. The generator is implementation-defined (and, if it uses std::rand, it's implementation-defined whether that is safe), so you'll need to consult the documentation for the implementation you're using.

To be sure, you should use one of the other variants, providing either a thread-safe generator, or a separate generator for each thread.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644