473,320 Members | 1,821 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

About rand() in C

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.

Feb 27 '06 #1
6 2581
Roka wrote:
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.

--
Best regards,
Andrey Tarasevich

Feb 27 '06 #2
"Roka" <Ro*****@gmail.com> writes:
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Feb 27 '06 #3

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) ks***@mib.org <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>

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

Feb 27 '06 #4
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) ks***@mib.org <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>

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

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

Feb 27 '06 #5
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) ks***@mib.org <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>

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

Feb 27 '06 #6
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, ...

Feb 27 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

35
by: wired | last post by:
Hi, I've just taught myself C++, so I haven't learnt much about style or the like from any single source, and I'm quite styleless as a result. But at the same time, I really want nice code and I...
3
by: Gunnar | last post by:
Hello. Problem: How can I select K random values from the elements 0,1,2,3,4...,N-1 ? I don't know if there's an easy way of doing this, but here are suggestions for doing it. One way is...
36
by: Profetas | last post by:
Hi, I want to generate a random 8 bit number using rand(0 is that possible? to expecifu the base and the lenght? thanks
21
by: Marc Dansereau | last post by:
Hi all I am new to this forum and to the c programming language. If I understand, the random() function in C return numbers that follow a uniform distribution U(0,1). Can somebody know how to...
2
by: xcm | last post by:
#include <stdlib.h> static unsigned long int next = 1; int rand(void) { next = next * 1103515245 + 12345; return (unsigned int)(next/(2 * (RAND_MAX +1L)) % (RAND_MAX+1L)); }
4
by: Siam | last post by:
Hi all, I'm writing a shell language in c++ that supports the generation of random numbers, and by its nature, each command must be executed in a new thread. The call to the random function from...
13
by: Spiros Bousbouras | last post by:
The standard says that rand() should return a pseudo-random number but what does pseudorandom mean ? If an implementation of rand() always returned the same number would it be conforming ? What if...
5
by: ds | last post by:
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...
10
by: Rafael Cunha de Almeida | last post by:
Hi, I've found several sites on google telling me that I shouldn't use rand() % range+1 and I should, instead, use something like: lowest+int(range*rand()/(RAND_MAX + 1.0))
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.