2015-12-14 1 views
0

Я начинаю программировать много потоков. У меня есть домашнее задание, в котором я должен создать некоторое количество потоков (в моем случае 10) и создать случайное число внутри каждого из них. , когда я отлаживаю свой код (или добавляю команду «sleep (1)»), он работает правильно, иначе сгенерированные значения больше не равны. , пожалуйста, помогите мне и объясните мне, если вы думаете, что есть что-то, что я до сих пор не понимаю. Код:pthread создает управляющие значения, сгенерированные в функции (в c)

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

int rn, sharedArray[10]; 
pthread_mutex_t lock; 


int randomgenerator(){ 
    //sleep(1); 
    srand(time(NULL)); // The value of random depend on the time with some changes in the time library 
    int rn, MAX = 10; // between 0 and 10 
    rn = rand()%MAX; 
    return rn; 
} 

void *rgen(void *arg){ 
    int order = (int*)arg; 
    //pthread_mutex_lock(&lock); 
    int rn = randomgenerator(); 
    printf("%d,%d\n", order,rn); //not working without printf why???? 
    sharedArray[order]= rn; 
    //pthread_mutex_unlock(&lock); 
    pthread_exit(NULL); 
} 

void main(int argc, char *argv[]){ 
    pthread_mutex_init(&lock, NULL); 
    pthread_t th[10]; 
    int i; 
    for (i = 0; i <10; i ++){ 
     pthread_create(&(th[i]), 0, rgen, (void *)i); 
     pthread_join(th[i], NULL); 
    } 

    int j, result = 0; 
    for (j=0; j<10; j++){ 
     result = sharedArray[j] + result; 
    } 
    printf("the final result is: %d\n",result); 
    pthread_exit(NULL); 
    pthread_mutex_destroy(&lock); 
} 

И выход:

0,3 
1,3 
2,3 
3,3 
4,3 
5,3 
6,3 
7,3 
8,3 
9,3 
the final result is: 30 

выход, который я ожидаю с раскомментирован сна является:

0,7 
1,4 
2,1 
3,8 
4,5 
5,2 
6,9 
7,6 
8,3 
9,0 
the final result is: 45 
+0

С первого взгляда я обеспокоен тем, как вы передаете свою пустоту * на pthreads. См. Http://stackoverflow.com/questions/8487380/how-to-cast-an-integer-to-void-pointer и http://stackoverflow.com/questions/8618637/what-does-it-mean- to-convert-int-to-void-or-vice-versa для получения дополнительной информации об этом. Большая проблема в основном заключается в том, что вы пытаетесь отбросить целое число до void *, даже не используя оператор & в любом случае, посмотрите на их «правильные» способы сделать это. – arduic

+0

Кроме того, вы запускаете 1 поток и вызываете соединение в этом потоке. Это приведет только к одному потоку. Вы должны разделить цикл и запустить все потоки, а не выполнять соединение. – brano

ответ

1

Проблема эта линия:

srand(time(NULL)); 

T он человек страница рандов/srand говорит:

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

Вы устанавливаете новое семя каждый раз. Это не правильно! You should only call srand once.

Когда вы прокомментируете сон, все потоки задают одно и то же семя, а затем получают первое случайное число в этой последовательности. Если они делают это за одну секунду, каждый из них получает одно и то же случайное значение.

Решение:

Переместить вызов srand в main, прежде чем создавать темы.

Примечание:

Функция рандов() не может использоваться повторно или поточно-, так как он использует скрытое состояние, которое модифицируется при каждом вызове.

Это означает, что вы не можете безопасно звонить rand одновременно из нескольких потоков. Вы должны либо защитить вызов, используя мьютекс, либо семафор, либо переключиться на повторную функцию, например rand_r.

Смежные вопросы