2009-05-17 5 views
1

захожу в странные проблемы в PTHREAD программирования Я составил следующий код в VS2005 с pthread-w32VS рандов() проблема с PTHREAD-win32

#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; 
} 

и выход, как это

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

Это похоже на то, что rand() возвращает один и тот же результат во всех двух вызовах , и у меня есть srand(), но результат не меняется каждый раз, когда я запускаю программу

Я очень новичок в многопоточном программировании, и я слышал о rand(), который не является потокобезопасным. но я все еще не могу понять, является ли программа выше неправильной или функция rand() имеет некоторые проблемы в ней.

+0

Связанный вопрос SO: [Является ли Windows rand_s потокобезопасным?] (Http://stackoverflow.com/questions/143108/is-windows-rand-s-thread-safe) –

ответ

4

rand является только псевдослучайным и будет возвращать одну и ту же последовательность каждый раз. srand работает только с текущим потоком, поэтому вызов его в основном потоке не повлияет на ваши рабочие потоки.

Вы должны вызвать srand внутри каждого потока со значением, который отличается для каждого потока - например, в пределах ваших thread1 и thread2 функции:

srand((int)time(NULL)^(int)pthread_getthreadid_np()); 
+0

благодарит много , но мне интересно почему srand() работает только с текущим потоком? – jagttt

+1

, вероятно, использует потоковое локальное хранилище - каждый поток будет иметь свою собственную копию семени случайных чисел – 2009-05-17 06:31:57

1

Попробуйте использовать rand_s() вместо этого потокобезопасно , См. here. Конечно, это не переносимо.