About rand() in C

R

Roka

Hi all.
I'm reading a program which used the sentence below:

#define NUM_THREADS 10
... ...
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.
 
A

Andrey Tarasevich

Roka said:
I'm reading a program which used the sentence below:

#define NUM_THREADS 10
... ...
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.
 
K

Keith Thompson

Roka said:
I'm reading a program which used the sentence below:

#define NUM_THREADS 10
... ...
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.
 
R

Roka

Keith said:
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.

Well, The complete code is :

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#define NUM_THREADS 6

void *thread_function(void *arg);

int main() {

int res;
pthread_t a_thread[NUM_THREADS];
void *thread_result;
int lots_of_threads;


for(lots_of_threads = 0; lots_of_threads < NUM_THREADS;
lots_of_threads++) {

res = pthread_create(&(a_thread[lots_of_threads]), NULL,
thread_function, (void *)lots_of_threads);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
/* sleep(1); */
}

printf("Waiting for threads to finish...\n");
for(lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0;
lots_of_threads--) {
res = pthread_join(a_thread[lots_of_threads], &thread_result);
if (res == 0) {
printf("Picked up a thread\n");
} else {
perror("pthread_join failed");
}
}

printf("All done\n");

exit(EXIT_SUCCESS);
}

void *thread_function(void *arg) {
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);

pthread_exit(NULL);
}

Edit the NUM_THREADS you can find rand_num is changing.
 
W

websnarf

Roka said:
Keith said:
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.

Well, The complete code is :

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#define NUM_THREADS 6

void *thread_function(void *arg);

int main() {

int res;
pthread_t a_thread[NUM_THREADS];
void *thread_result;
int lots_of_threads;


for(lots_of_threads = 0; lots_of_threads < NUM_THREADS;
lots_of_threads++) {

res = pthread_create(&(a_thread[lots_of_threads]), NULL,
thread_function, (void *)lots_of_threads);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
/* sleep(1); */
}

printf("Waiting for threads to finish...\n");
for(lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0;
lots_of_threads--) {
res = pthread_join(a_thread[lots_of_threads], &thread_result);
if (res == 0) {
printf("Picked up a thread\n");
} else {
perror("pthread_join failed");
}
}

printf("All done\n");

exit(EXIT_SUCCESS);
}

void *thread_function(void *arg) {
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);

pthread_exit(NULL);
}

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
after your produce new threads. If its anything like the typical
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.
 
?

=?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=

Roka said:
Keith said:
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.

Well, The complete code is :

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#define NUM_THREADS 6

void *thread_function(void *arg);

int main() {

int res;
pthread_t a_thread[NUM_THREADS];
void *thread_result;
int lots_of_threads;


for(lots_of_threads = 0; lots_of_threads < NUM_THREADS;
lots_of_threads++) {

res = pthread_create(&(a_thread[lots_of_threads]), NULL,
thread_function, (void *)lots_of_threads);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
/* sleep(1); */
}

printf("Waiting for threads to finish...\n");
for(lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0;
lots_of_threads--) {
res = pthread_join(a_thread[lots_of_threads], &thread_result);
if (res == 0) {
printf("Picked up a thread\n");
} else {
perror("pthread_join failed");
}
}

printf("All done\n");

exit(EXIT_SUCCESS);
}

void *thread_function(void *arg) {
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);

pthread_exit(NULL);
}

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.
 
R

Roka

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, ...
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top