views:

387

answers:

3

I come into a strange problem in pthread programming I've compiled the following code in vs2005 with pthread-w32

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <pthread.h>
#include <windows.h>

pthread_mutex_t lock;

void* thread1(void *) {
  int r1;
  while(true) {
    pthread_mutex_lock(&lock); // rand is maybe a CS
    r1 = rand() % 1500;
    pthread_mutex_unlock(&lock);
    Sleep(r1); printf("1:%d\n", r1);
  }
  return NULL;
}

void* thread2(void *) {
  int r2;
  while(true) {
    pthread_mutex_lock(&lock);
    r2 = rand() % 1500;
    pthread_mutex_unlock(&lock);
    Sleep(r2); printf("2:%d\n", r2);
  }
  return NULL;
}

int main() {
  srand((int)time(NULL));
  pthread_mutex_init(&lock, NULL);

  pthread_t tc_p, tc_v;
  pthread_create(&tc_p, NULL, thread1, NULL);
  pthread_create(&tc_v, NULL, thread2, NULL);

  pthread_join(tc_p, NULL);
  pthread_join(tc_v, NULL);

  pthread_mutex_destroy(&lock);

    return 0;
}

and output is like this

2:41
1:41
1:467
2:467
1:334
2:334
1:1000
2:1000

it's just like that rand() is return the same result in every two calls and i have srand() but the result doesn't change each time i run the program

i'm very new to multi thread programming and i've heard about the rand() is not thread safe. but i still can't figure out if the program above is wrong or the rand() function has some problem in it.

+1  A: 

rand is only pseudo-random, and will return the same sequence each time. srand only works on the current thread, so calling it in your main thread won't affect your worker threads.

You need to call srand from within each thread, with a value that's different for each thread - for instance, within your thread1 and thread2 functions:

srand((int)time(NULL) ^ (int)pthread_getthreadid_np());
RichieHindle
thanks a lotbut I wonder why srand() only works on current thread?
lilo
probably uses thread-local storage - each thread will have its own copy of the random number seed
anon
+1  A: 

Try using rand_s() instead, it is thread-safe. See here. Of course, it's not portable.

rlbond
A: 

Related SO question: Is Windows’ rand_s thread-safe?

Mitch Wheat