Peculiar rand() case and threads

D

ds

Hi all,

rand() is not thread safe, a fact that may not be so bad after all..
However, I face the following problem: a piece of code uses rand() to
get a random sequence, but always seeds with the same seed for
reproducibility of the results. Now I am porting this (old C89) code
and have setup a nice app with threads that drives on one thread the
old code and on another the new code, so that I can compare the
results and see that nothing changed. Alas, rand() is not thread safe
so even though both versions seed with the same number, consecutive
rand() calls do not yield the same number for each thread... I would
like to setup a workaround in the new code only rather than make
changes to the old code as well. Any ideas?

Thanks a lot in advance!!!!

BR

-- ds
 
M

mlimber

rand() is not thread safe, a fact that may not be so bad after all..
However, I face the following problem: a piece of code uses rand() to
get a random sequence, but always seeds with the same seed for
reproducibility of the results. Now I am porting this (old C89) code
and have setup a nice app with threads that drives on one thread the
old code and on another the new code, so that I can compare the
results and see that nothing changed. Alas, rand() is not thread safe
so even though both versions seed with the same number, consecutive
rand() calls do not yield the same number for each thread... I would
like to setup a workaround in the new code only rather than make
changes to the old code as well. Any ideas?

Threads are not part of standard C++, so your question is off-topic
here. See <http://www.parashift.com/c++-faq-lite/how-to-
post.html#faq-5.9>.

<OT>
Just protect calls that affect the random number generation with a
mutex (or whatever the equivalent is called on your system). See this
article on Boost.Threads for a similar example in which the standard
input/output must be protected: <http://www.ddj.com/dept/cpp/
184401518>.
</OT>

Cheers! --M
 
D

ds

Hi,

thanks for the reply. My question is more related to rand() rather
than threads ;-) and whether there is some access function. Apparently
there is rand_r() which is reentrant, but it does not yield the same
sequence (or I do not know how to make it do so...). Thanks a lot!!!


BR

-- ds
 
M

mlimber

thanks for the reply. My question is more related to rand() rather
than threads ;-) and whether there is some access function. Apparently
there is rand_r() which is reentrant, but it does not yield the same
sequence (or I do not know how to make it do so...). Thanks a lot!!!

It's still intimately tied to threading -- if you reduce it to a
single-threaded case, there's no problem. I'd suggest you ask on
comp.programming.threads or a newsgroup for your OS or threading
library.

<OT>
Re-reading your original post, I take it that you want two threads to
use the random number generator simultaneously but without getting
different results. So if the random sequence is { 2, 5, 3, 1 }, you
want both threads to get this sequence in the exact same order (rather
than thread 1 seeing, say, { 2, 3 } and thread 2 seeing { 5, 1 } or
something). If so, I think you'll need to implement some sort of
queueing of the random numbers based on thread id or whatever. Ask for
more details on a more appropriate group, and you might get a more
insightful response.
</OT>

Cheers! --M
 
P

Puppet_Sock

rand() is not thread safe, a fact that may not be so bad after all..
However, I face the following problem: a piece of code uses rand() to
get a random sequence, but always seeds with the same seed for
reproducibility of the results. Now I am porting this (old C89) code
and have setup a nice app with threads that drives on one thread the
old code and on another the new code, so that I can compare the
results and see that nothing changed. Alas, rand() is not thread safe
so even though both versions seed with the same number, consecutive
rand() calls do not yield the same number for each thread... I would
like to setup a workaround in the new code only rather than make
changes to the old code as well. Any ideas?

One not-too-hard suggestion: Ditch the built in rand
and get your own. There are a variety of them available
for free on the net, plus just about every numerical
text will have source code for at least one. It will
not be too hard to find one with better stats than the
built in rand.

Then make yourself a tiny little class that accepts
a seed, then makes calls to your own rand fucntion.
Apart from the rand function, should only be ten or
twenty lines of code.

Then have each thread make an instance of its own
rand generating object. Thread safety should be fairly
easy to have as a built-in.

The built in rand is often not very good. Unless you
are doing nothing more important than writing a game,
and maybe not even then, the built in rand is not
going to provide adequate quality random numbers.
Socks
 
R

rossum

Hi all,

rand() is not thread safe, a fact that may not be so bad after all..
However, I face the following problem: a piece of code uses rand() to
get a random sequence, but always seeds with the same seed for
reproducibility of the results. Now I am porting this (old C89) code
and have setup a nice app with threads that drives on one thread the
old code and on another the new code, so that I can compare the
results and see that nothing changed. Alas, rand() is not thread safe
so even though both versions seed with the same number, consecutive
rand() calls do not yield the same number for each thread... I would
like to setup a workaround in the new code only rather than make
changes to the old code as well. Any ideas?

Thanks a lot in advance!!!!

BR

-- ds
I assume that you want to have both threads use the same series of
random numbers, rather than each use a different half of the series.
That means you will have to remember the numbers rand() generates so
that each number can be passed to both threads in the correct order.

To make the built-in rand() thread safe you could put it into a class
of its own. Off the top of my head, you could use the real rand() to
populate two queues. One queue feeds your "old" thread via one
interface (say rand1())and the other queue feeds your "new" thread via
a second interface (rand2()). When either queue is exhausted, cycle
rand() a few times and add the numbers generated to both queues. Each
thread can only use its appropriate interface, rand1() or rand2().
You say that you don't want to change your old code. Would
#define rand rand1
count?

rossum
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,125
Latest member
VinayKumar Nevatia_
Top