14

The caption pretty much says it.

PS. This is for C++ Windows program.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
ahmd0
  • 16,633
  • 33
  • 137
  • 233

4 Answers4

17

According to the MSDN documentation on srand() (assuming you are using Microsoft's C runtime library), the seed is thread-local, so you need to call srand() for each thread that is using rand(). Note that this may not be the case in other implementations.

Quoting from MSDN:

The srand function sets the starting point for generating a series of pseudorandom integers in the current thread.

Jori
  • 1,122
  • 2
  • 18
  • 36
dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • I think that is non-standard. – Nawaz Apr 15 '12 at 05:18
  • 2
    @Nawaz: It is non-standard, POSIX doesn't require `srand()` or `rand()` to be thread-safe. – dreamlax Apr 15 '12 at 05:20
  • Thanks. I missed it. So, yes, it seems that every thread needs to seed it first... what a hassle. – ahmd0 Apr 15 '12 at 05:20
  • 1
    The point of `rand()` is that it generates a fixed sequence starting from a seed. It's hard to see how that's useful when calls from other threads can modify the sequence that the calling thread gets. (Of course, it's a fair argument that even if this is a fix, it's a landmine, since the function has the same name but different semantics.) – David Schwartz Apr 15 '12 at 05:38
5

Even if the answer weren't platform specific I'd suggest you avoid srand() and use <random> instead. Not only does the C++11 <random> library provide clear semantics in multithreaded programs but it also provides much better facilities for random number generation. It provides several different random number generators to meet different quality, speed, and size requirements, and many standard distributions so you won't make the mistakes people often do when using rand.

bames53
  • 86,085
  • 15
  • 179
  • 244
2

No, as per the Standard, because once you call srand() it affects rand() calls from all threads.

C library function srand() is single-threaded just like all other functions are, which means if you call srand() from one thread, it affects the number-seqeunce generated from rand() in other threads as well.

But Microsoft provides non-standard srand() which does require you to call it from all threads.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    Well, technically this is the correct answer too, although you should've said, "Yes" in your opening statement -- meaning, yes, to call it per every thread, right )) – ahmd0 Apr 15 '12 at 05:22
  • 3
    @ahmd0: It is supposed to be `No`, as per the Standard. – Nawaz Apr 15 '12 at 05:30
  • There only standards Microsoft violates are the POSIX threading standard and the C++11 standards, neither of which Microsoft claims to conform to. Microsoft's function isn't non-standard, it conforms to the Windows threading standard, which differs from the POSIX standard in many ways. This is just one of them. (And Microsoft got it right, POSIX/ISO got it wrong. See my comment above.) – David Schwartz Apr 15 '12 at 05:40
  • @DavidSchwartz Microsoft claims support for c++11. In particular I've heard Herb Sutter say they've got complete support for the C++11 standard library. (of course I know of a number of ways that's not true in other areas, due to lack of language feature) – bames53 Apr 15 '12 at 05:44
  • @bames53 My sources only say that they are adding many C++11 features and working towards C++11 compliance. Just two months ago, they sent developers a survey asking them to prioritize C++11 features to help them decide what to add. I wonder if a version that claims C++11 compliance will have a 'fixed' `srand`. (I'm not 100% certain that's required for C++11 compliance, but I do believe that it is.) – David Schwartz Apr 15 '12 at 05:47
  • @DavidSchwartz it looks like its not required by c++11 anyway. The spec only mentions srand once by listing its existence. – bames53 Apr 15 '12 at 05:53
  • @DavidSchwartz: I agree with you, having the seed as thread-local makes more sense, and I find it strange that even in C11 `srand()` and `rand()` are not required to avoid data races despite the language now having standardised threading support. – dreamlax Apr 15 '12 at 07:27
0

Be aware that the state is fiber-local (which is more fine-grained than thread-local). Thus, srand has to be called for each fiber. (Of course, when you don't use fibers it's equivalent to thread-local.)

tobias.loew
  • 161
  • 2
  • 8