Velocity Reviews > About rand() in C

Roka
Guest
Posts: n/a

 02-27-2006
Hi all.
I'm reading a program which used the sentence below:

... ...
int rand_num;
rand_num = 1+ (int) (9.0 * rand() / (RAND_MAX + 1.0));
sleep(rand_num);
... ...
(The program is long so I used a part of it.)

When NUM_THREADS is 10 , I see rand_num has a range of 0 to 9.
When NUM_THREADS is 20 , I see rand_num has the range of 0 to 19.

My question is how does that work?
It seems that rand_num has no relation to NUM_THREADS.

THANKS.

Andrey Tarasevich
Guest
Posts: n/a

 02-27-2006
Roka wrote:
> I'm reading a program which used the sentence below:
>
> ... ...
> int rand_num;
> rand_num = 1+ (int) (9.0 * rand() / (RAND_MAX + 1.0));
> sleep(rand_num);
> ... ...
> (The program is long so I used a part of it.)
>
> When NUM_THREADS is 10 , I see rand_num has a range of 0 to 9.
> When NUM_THREADS is 20 , I see rand_num has the range of 0 to 19.
>
> My question is how does that work?
> It seems that rand_num has no relation to NUM_THREADS.
> ...

You probably got the wrong part of the program. Firstly, the code you
quoted will never produce 0 in 'rand_num'. Secondly, as you already
noticed, it doesn't depend on NUM_THREADS.

--
Best regards,
Andrey Tarasevich

Keith Thompson
Guest
Posts: n/a

 02-27-2006
"Roka" <(E-Mail Removed)> writes:
> I'm reading a program which used the sentence below:
>
> ... ...
> int rand_num;
> rand_num = 1+ (int) (9.0 * rand() / (RAND_MAX + 1.0));
> sleep(rand_num);
> ... ...
> (The program is long so I used a part of it.)
>
> When NUM_THREADS is 10 , I see rand_num has a range of 0 to 9.
> When NUM_THREADS is 20 , I see rand_num has the range of 0 to 19.
>
> My question is how does that work?
> It seems that rand_num has no relation to NUM_THREADS.

You're right, rand_num has no relation to NUM_THREADS, at least not in
the code you posted.

The statement above will assign a value in the range 1 to 9 (not 0 to
9). If the result depends on NUM_THREADS, it must be because of some
code you haven't shown us.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Roka
Guest
Posts: n/a

 02-27-2006

Keith Thompson wrote:
>
> You're right, rand_num has no relation to NUM_THREADS, at least not in
> the code you posted.
>
> The statement above will assign a value in the range 1 to 9 (not 0 to
> 9). If the result depends on NUM_THREADS, it must be because of some
> code you haven't shown us.
>
> --
> Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
> We must do something. This is something. Therefore, we must do this.

Well, The complete code is :

#include <stdio.h>

#include <stdlib.h>

int main() {

int res;

if (res != 0) {
exit(EXIT_FAILURE);
}
/* sleep(1); */
}

if (res == 0) {
} else {
}
}

printf("All done\n");

exit(EXIT_SUCCESS);
}

int my_number = (int)arg;
int rand_num;

printf("thread_function is running. Argument was %d\n", my_number);
rand_num=1+(int)(9.0*rand()/(RAND_MAX+1.0));
sleep(rand_num);
printf("Bye from %d\n", my_number);

}

Edit the NUM_THREADS you can find rand_num is changing.

websnarf@gmail.com
Guest
Posts: n/a

 02-27-2006
Roka wrote:
> Keith Thompson wrote:
> > You're right, rand_num has no relation to NUM_THREADS, at least not in
> > the code you posted.
> >
> > The statement above will assign a value in the range 1 to 9 (not 0 to
> > 9). If the result depends on NUM_THREADS, it must be because of some
> > code you haven't shown us.
> >
> > --
> > Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
> > San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
> > We must do something. This is something. Therefore, we must do this.

>
> Well, The complete code is :
>
> #include <stdio.h>
>
> #include <stdlib.h>
>
>
>
>
> int main() {
>
> int res;
>
>
>
> if (res != 0) {
> exit(EXIT_FAILURE);
> }
> /* sleep(1); */
> }
>
> printf("Waiting for threads to finish...\n");
> if (res == 0) {
> } else {
> }
> }
>
> printf("All done\n");
>
> exit(EXIT_SUCCESS);
> }
>
> int my_number = (int)arg;
> int rand_num;
>
> printf("thread_function is running. Argument was %d\n", my_number);
> rand_num=1+(int)(9.0*rand()/(RAND_MAX+1.0));
> sleep(rand_num);
> printf("Bye from %d\n", my_number);
>
> }
>
> Edit the NUM_THREADS you can find rand_num is changing.

There are a number of conceptual things going on here that makes rand()
look like its not behaving like rand().

First of all, I don't know how the state is maintained between threads
implementation (with a shared state), however, it will be subject to
bizarre race conditions where two threads can get the same random
number, and in fact the random number generator can appear to go
backwards along it sequence. rand() is generally not thread safe, and
it would probably be hard to convince compiler vendors to make it so,
even though they probably should (that along with the strtok static,
and various other stateful statics should probably all be thrown into
thread local storage, just to give the system some semblance of
sanity.)

Second, performing sleep(1 ... 9) is just going to be too small of a
sleep interval. It may take longer for the next thread to be spawned
than for the sleep() to time out. That is to say, the threads are not
all being launched at once, and in fact the sequence of launching may
in fact be slower than the sleep timeouts for the threads that are
currently running thus causing them to end before new threads are
started. Thus you will not see the random wake up and die ordering
than you are expecting. It may be as simple as changing the formula
you use to something like:

rand_num=100+(int)(100.0*rand()/(RAND_MAX+1.0));

The threads should all launch well before the first one wakes up and
exits. The sleep time taken will also be spread out enough that the
order in which they were launched will not significantly affect their
order of waking up.

Oh and BTW, this is not a UNIX or multitasking newsgroup. Its an ANSI
C standard newsgroup. Unfortunately, there's no charter or FAQ or
anything resembling a hint to tell you that, but apparently that is the
case. In the future you should ask questions like this in other groups
like comp.programming.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

=?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=
Guest
Posts: n/a

 02-27-2006
Roka wrote:
> Keith Thompson wrote:
>> You're right, rand_num has no relation to NUM_THREADS, at least not in
>> the code you posted.
>>
>> The statement above will assign a value in the range 1 to 9 (not 0 to
>> 9). If the result depends on NUM_THREADS, it must be because of some
>> code you haven't shown us.
>>
>> --
>> Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
>> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
>> We must do something. This is something. Therefore, we must do this.

>
> Well, The complete code is :
>
> #include <stdio.h>
>
> #include <stdlib.h>
>
>
>
>
> int main() {
>
> int res;
>
>
>
> if (res != 0) {
> exit(EXIT_FAILURE);
> }
> /* sleep(1); */
> }
>
> printf("Waiting for threads to finish...\n");
> if (res == 0) {
> } else {
> }
> }
>
> printf("All done\n");
>
> exit(EXIT_SUCCESS);
> }
>
> int my_number = (int)arg;
> int rand_num;
>
> printf("thread_function is running. Argument was %d\n", my_number);
> rand_num=1+(int)(9.0*rand()/(RAND_MAX+1.0));
> sleep(rand_num);
> printf("Bye from %d\n", my_number);
>
> }
>
> Edit the NUM_THREADS you can find rand_num is changing.

No it doesn't. You should insert a statement
such as e.g. printf("Genereated prng %d\n",rand_num); after
your line with rand() to check.

Roka
Guest
Posts: n/a

 02-27-2006

> No it doesn't. You should insert a statement
> such as e.g. printf("Genereated prng %d\n",rand_num); after
> your line with rand() to check.

Oops. I made a mistake. I'm sorry, ...