3

I'm trying to run this very simple code which generate a random number between 0 to 99 using multithreading:

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


void * NumGen(void * tid){
    int a = 0;
    a = rand() % 100;
    printf("a: %d\n",a);
};

int main()
{
    srand(time((NULL)));
    pthread_t tid0;
    pthread_t tid1;
    pthread_t tid2;
    pthread_t * pthreads[] = {&tid0,&tid1,&tid2};

    for (int i = 0; i < 3; i++)
        pthread_create(pthreads[i],NULL,NumGen,NULL);

    pthread_join(tid0, NULL);
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

Although I used srand(time((NULL))), the output I get is:

a: 41
a: 41
a: 41

What is the reason that I don't get different number each time? Thanks

idop
  • 31
  • 1
  • @SimonGoater: I am still reviewing what the C standard has to say about this, but I do not believe the pseudo-random data has to be separated by thread, and, if it is not, each thread calling `srand` will merely update the state for all threads and not prevent them from using the same state, with data races. C 2018 7.22.2.2 3 and 7.22.2.1 3 say that `srand` and `rand` do not have to avoid data races, which suggests they may be using data shared between threads. – Eric Postpischil Apr 22 '23 at 13:47
  • 1
    Does this answer your question? [Using stdlib's rand() from multiple threads](https://stackoverflow.com/questions/6161322/using-stdlibs-rand-from-multiple-threads) – Tsyvarev Apr 22 '23 at 13:51
  • 1
    Depending on what OS you're using, there are better options available than `rand()`, like [`random_r()`](https://man7.org/linux/man-pages/man3/random_r.3.html), which on Linux can be seeded with [`getentropy()`](https://man7.org/linux/man-pages/man3/getentropy.3.html). – Shawn Apr 22 '23 at 13:52
  • @EricPostpischil I eagerly await for an authoritative answer then. Wow, rand() not thread safe? – Simon Goater Apr 22 '23 at 13:53
  • 1
    7.1.4 5 says a library function shall not access objects accessible by threads other than the current thread except when this is due to the function’s arguments. For `srand` and `rand`, the standard says they are not required to avoid data races. I was reluctant to interpret that to mean they may access shared objects. However, 7.1.4 5 starts with “Unless explicitly stated otherwise… library functions shall prevent data races as follows:”. So I interpret that to mean that, if a library function is not required to prevent a data race, the rule against accessing shared objects does not apply. – Eric Postpischil Apr 22 '23 at 13:53
  • POSIX says it doesn't *have* to be thread safe, linux/glibc man page says their version is. – Shawn Apr 22 '23 at 13:56
  • 1
    What happens when you serialize the calls to `rand` by using a mutex, so that only one thread calls `rand` at a time? Do you get the same result? – Andreas Wenzel Apr 22 '23 at 14:44

0 Answers0