About rand() in C

Discussion in 'C Programming' started by Roka, Feb 27, 2006.

  1. Roka

    Roka Guest

    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.
     
    Roka, Feb 27, 2006
    #1
    1. Advertising

  2. 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
     
    Andrey Tarasevich, Feb 27, 2006
    #2
    1. Advertising

  3. "Roka" <> 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) <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.
     
    Keith Thompson, Feb 27, 2006
    #3
  4. Roka

    Roka Guest

    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) <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.
     
    Roka, Feb 27, 2006
    #4
  5. Roka

    Guest

    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) <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, 2006
    #5
  6. 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) <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.
     
    =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Feb 27, 2006
    #6
  7. Roka

    Roka Guest


    > 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, ...
     
    Roka, Feb 27, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Niko D. Barli

    rand function in Modelsim 5.7c

    Niko D. Barli, Aug 26, 2004, in forum: VHDL
    Replies:
    9
    Views:
    6,374
    Niko D. Barli
    Sep 6, 2004
  2. daniel kaplan

    rand() question

    daniel kaplan, Sep 15, 2004, in forum: Perl
    Replies:
    4
    Views:
    636
    Ian Sedwell
    Sep 21, 2004
  3. Amelyan

    what is rand?

    Amelyan, Mar 31, 2006, in forum: ASP .Net
    Replies:
    3
    Views:
    555
    Kevin Spencer
    Mar 31, 2006
  4. Orhan Demirel

    usage of rand()

    Orhan Demirel, Jul 21, 2003, in forum: C++
    Replies:
    1
    Views:
    400
    Adam Fineman
    Jul 21, 2003
  5. 7stud --

    rand() v. rand(0.1) ?

    7stud --, Sep 15, 2007, in forum: Ruby
    Replies:
    6
    Views:
    247
    Morton Goldberg
    Sep 16, 2007
Loading...

Share This Page