5

I am writing a program where there are worker threads which create random numbers from 0 to 3 from 0 to x-1(a variable)

what i need to learn is that how can i produce these random numbers in C.

I am using gcc compiler and working on Ubuntu 11.10

5
  • 2
    What is meant by 'from 0 to 3 from 0 to x-1'? Do you mean you need x random values lying between 0 to 3 Commented Jan 7, 2012 at 13:27
  • 1
    Are you asking what to learn about the random part or multithreading part or both? Commented Jan 7, 2012 at 13:29
  • x is the name of a int variable. Commented Jan 7, 2012 at 13:29
  • 1
    If you're on a POSIX system, try one of the drand48 functions (possibly nrand48()). Commented Jan 7, 2012 at 13:34
  • @littlestewie: Please provide details of your environment(platform,compiler) Since the answer would depend on that. Commented Jan 7, 2012 at 14:14

5 Answers 5

9

rand() & srand() are not the ones that can be used safely in that case.

They both are neither re-entrant nor threadsafe. Generally speaking, neither C or the C++ standards pose any requirements about thread safety on any of the standard library functions.
Some implementations may indeed provide thread safe versions but it is not mandated by the standard.

To be able to use a random number generator in multithreaded environment You will need a implementation that allows passing in the state. This way, you can keep one state value per thread, and generate good quality random numbers without requiring synchronization.

The C standard library does not provide any choices. That makes 100% portability rather impossible.The choice of usage would then depend on your environment which you should mention as a part of your question to get accurate answers.

Have a look at GNU Scientific Library which claims to provide MultiThreaded Random Number generator.

Sign up to request clarification or add additional context in comments.

5 Comments

I have used GSL for this before without problems on Linux and Windows - note that each thread needs its own random number generator (created using gsl_rng_alloc). That is, thread safety is achieved by having multiple random number generators, each with their own state, rather than by locking the state each time the generator is used.
Normally, when a function isn't thread safe, you can get unxepected results. But if rand returns unexpected results, what's the problem?
@ugoren: You might end up getting the exact same values from a function which is supposed to give you random values, Is that not a problem?
@Als, A correct rand() implementation would also give the exact same random values twice, with some probability. But in principle you're right, because with a correct rand() it's a known probability, and here it isn't. If it's used for cryptography, it can actually matter.
In simulation studies, you often want to be able to replicate the results of the "randomly" simulated data. That's why random number generators usually allow you to personally set the seed. So it can matter.
1

If you just want some random numbers and do not care whether the random number serials be generated independently or not, you can still use rand() and srand().

    #include <stdlib.h>                       
    #include <stdio.h>                        
    #include <pthread.h>                      
    #include <unistd.h>                       

    void* cb1(void*) {                        
        while(1) {                            
            printf("cb1, rand:%d\n",rand());  
            sleep(1);                         
        }                                     
    }                                         

    void* cb2(void*) {                        
        while(1) {                            
            printf("cb2, rand:%d\n",rand());  
            sleep(1);                         
        }                                     
    }                                         


    int main() {                              
        pthread_t  th1, th2;                  
        srand(1);                             
        pthread_create(&th1, NULL, cb1, NULL);
        pthread_create(&th2, NULL, cb2, NULL);

        pthread_join(th1, NULL);              
        pthread_join(th2, NULL);              

        return 0;                             
    }                                         

Comments

1

Use rand_r() (see rand(3))

The function rand_r() is supplied with a pointer to an unsigned int, to be used as state.

It is reentrant and takes the seed as an input, so the threads can manage their seeds separately.

Comments

0

A thing of truth and beauty;

http://en.wikipedia.org/wiki/Mersenne_twister

Write your own RNG.

(Apologies. I've just looked at that wiki page. Last I looked, a while back, it was fine; you could read it and implement the twister. Now it's a bunch of degree level maths which explains absolutely nothing to anyone, barring the subset of the population who spent four years at University studying mathmathics. I see this happen a lot on the wiki :-(

2 Comments

Maybe not for long - I had the impression there was a fight in the discussion about how the psuedocode wasn't psuedocode. Expect the page to be completely useless in the near future :-/
Don't write your own for production use. Just don't. There exist well debugged implementations.
0

A simple version, lacking error checking, using C11's threads.h would look like this:

mtx_t rand_mtx;

//run only once.
int rand_init(int seed)
{
     srand(seed);
     mtx_init(&rand_mtx, mtx_plain);
} 

int synced_rand()
{
    mtx_lock(&rand_mtx);
    int r = rand();
    mtx_unlock(&rand_mtx);
    return r;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.