2013-08-05 13 views
1

我想在C中開發一個程序,將生成給定數量的隨機整數。它應該使用一定數量的線程來加速。我發現常規的隨機函數不適用於線程,現在正在使用random_r。我一直在initstate_r函數中獲取SegFault,這是沒有意義的,因爲我試圖初始化變量,而不是訪問它們。任何人都可以告訴我我在這裏做錯了什麼? (該initstate_r功能需要留在generateRandomNumbers功能。)多線程隨機數發生器不斷得到一個SegFault在initstate_r函數

下面是代碼:

#include <errno.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> // must include stdio for pvm3.h to compile correctly 
#include <sys/times.h> /* for times system call */ 
#include <sys/time.h> /* for gettimeofday system call */ 
#include <pthread.h> 

/*#define DEBUG 1*/ 

#define RANDOM_SEED 12345678 

//The main work routine 
//void generateRandomNumbers(long long); 
void *generateRandomNumbers(void *); 
double getMilliSeconds(); 

/* The main work routine */ 
//void generateRandomNumbers(long long int count) 
void *generateRandomNumbers(void *arg) 
{ 
    struct random_data buf; 
    int32_t result; 
    char rand_statebuf; 
    printf("hold 1\n"); 
    // This is the function that gives me a SegFault 
    initstate_r(RANDOM_SEED, &rand_statebuf, 128, &buf); 
    printf("hold 2\n"); 

    long long int* count = (long long int*) arg; 
    //printf("Count for thread ID# %ld is %lld\n", pthread_self(), *count); 
    long long int i; 
    //long int x; 

    srandom_r(RANDOM_SEED, &buf); 
    for (i = 0; i < *count; i++) { 
     random_r(&buf, &result); 
#ifdef DEBUG 
     printf("%ld\n", result); 
#endif 
    } 
    pthread_exit(NULL); 
} 


int main(int argc, char **argv) 
{ 
    long long int count, newCount; 
    int numThreads; 
    //pthread_t *tids; 

    double timeStart = 0; 
    double timeElapsed = 0; 

    if (argc < 3) { 
     fprintf(stderr, "Usage: %s <n>\n" ,argv[0]); 
     exit(1); 
    } 
    sscanf(argv[1],"%lld",&count); /* lld for long long int */ 
    sscanf(argv[2],"%d",&numThreads); 
    pthread_t tids[numThreads]; 
    newCount = count/numThreads; 

    timeStart = getMilliSeconds(); //And we are off 

    int i; 
    for (i=0; i<numThreads; i++) 
    { 
     pthread_create(&tids[i], NULL, generateRandomNumbers, (void *) &newCount); 
    //pthread_join(tids[i], NULL); 
    } 

    int j; 
    for (j=0; j<numThreads; j++) 
    { 
     pthread_join(tids[j], NULL); 
    } 

    //generateRandomNumbers(count); 
    printf("generated %lld random numbers\n", count); 

    timeElapsed = getMilliSeconds() - timeStart; 
    printf("Elapsed time: %lf seconds\n",(double)(timeElapsed/1000.0)); 
    fflush(stdout); 

    exit(0); 
} 
+0

也許generateRandomNumbers不是線程安全的,因爲每次調用都會更新靜態種子? – Jiminion

+0

@Matthew,我不熟悉pvm3,但是他們在代碼文檔(註釋)中是否有任何關於哪些函數是和不是線程安全的? – ryyker

+0

@Matthew - 另一個想法,再次,不熟悉你正在使用的庫,但多次使用隨機生成器,一個初始化函數(可能是如initstate_r)只能用於一次,在流程開始時說,以充滿泵。隨後的調用將繼續生成僞隨機數,直到進程停止。文檔對initstate_r的說明是什麼? – ryyker

回答

2

的問題是,initstate_r的第二個參數是應該是一個char *,

你做:

char rand_statebuf; 
printf("hold 1\n"); 
// This is the function that gives me a SegFault 
initstate_r(RANDOM_SEED, &rand_statebuf, 128, &buf); 

你給它傳遞一個指向1個字符的指針,它符合字符指針的要求,但是你需要比僅僅一個字符多得多的空間。它應該是:

char rand_statebuf[128]; 
initstate_r(RANDOM_SEED,rand_statebuf,sizeof(rand_statebuf),&buf); 
+1

推薦'initstate_r(RANDOM_SEED,rand_statebuf,sizeof(rand_statebuf),&buf);'還有,'128'也被認爲是足夠的?我能說的最好的是它必須是> = 8。 – chux

+0

有些文獻說:的狀態信息是8,32,64,128和256字節,數值向下舍入到最接近的已知值。「因此,256是最強大的? – chux

+0

修復它!謝謝! –