2016-10-28 2 views
1

Я пытаюсь реализовать многопоточную игру жизни в c. Программа считывает 2d-массив (A [100] [100]) размером 100x100 из файла, копирует его во второй массив (B [100] [100]) и создает 100 потоков, которым назначена часть 10x10 массива и потоки должны проверять соседние ячейки каждой ячейки (из массива A) и изменять статус в соответствии с правилами в массиве B, когда они заканчивают основную функцию, копирует B в A и запускает aggain от начала, пока пользователь не остановит программа. Моя проблема в том, что потоки только изменяют значения для последней части массива (позиции [90-99] [90-99]). может ли кто-нибудь задуматься о том, что может быть неправильным? (если я использую тот же код, но назначаю весь массив всем потокам, результат правильный, то же самое произойдет, если я использую только один поток)многопоточная игра жизни в c

+1

Несвязанной к вашей проблеме: но было бы разумно не использовать константы, такие как '100' и' 99', но '' BOARDSIZE' и BOARDSIZE-1'. Это позволяет вам изменять размер платы в одном месте, и ваш код будет более читабельным. –

+0

Вы пробовали какой-то базовый отладчик ??????? Вы видели внутри того, что происходит внутри памяти, когда вы пытаетесь написать/прочитать/от него? – Leos313

+0

80% из вас "check neighbour" не используется, если вы просто добавили предварительное условие к if. например A [i] [j-1] рассчитывает только, если j> 0, поэтому напишите 'if (j> 0 && A [i] [j-1])', а затем только один раз. нужен только последний блок else (с добавленными предварительными условиями) – Tommylee2k

ответ

2

Здесь:

int c[5]; 
for(i=0;i<100;i=i+10){ 
    for(j=0;j<100;j=j+10){ 
     c[0]=i; 
     c[1]=i+9; 
     c[2]=j; 
     c[3]=j+9; 
     c[4]=k; 
     err = pthread_create(&(tid[k++]),NULL, &populate, (void *)c); 
    } 
} 

Вы передаете один и тот же массив в каждый поток. Таким образом, все потоки будут иметь одинаковые параметры - независимо от того, какие конечные значения c находятся в конце циклов.

Вместо этого дайте каждому потоку свой собственный c:

int *c; 
for(i=0;i<100;i=i+10){ 
    for(j=0;j<100;j=j+10){ 
     c = malloc(5 * sizeof(*c)); 
     c[0]=i; 
     c[1]=i+9; 
     c[2]=j; 
     c[3]=j+9; 
     c[4]=k; 
     err = pthread_create(&(tid[k++]),NULL, &populate, (void *)c); 
    } 
} 
+0

работал как шарм, спасибо .. – panos3p

+0

YW. Кроме того, не забудьте 'free()' массивы, когда они больше не используются. –

0

ваших «has_neighbors» в целом много избыточного кода, который может быть удален либо с объединением rangechecks с проверкой контента,

... 
     if(i> 0 && j> 0 && A[i-1][j-1]==1) count++; 
     if(i> 0   && A[i-1][j ]==1) count++; 
     if(i> 0 && j<99 && A[i-1][j+1]==1) count++; 
     if(  j> 0 && A[i ][j-1]==1) count++; 
     if(  j<99 && A[i ][j+1]==1) count++; 
     if(i<99 && j> 0 && A[i+1][j-1]==1) count++; 
     if(i<99   && A[i+1][j ]==1) count++; 
     if(i<99 && j<99 && A[i+1][j+1]==1) count++; 
     return count; 
    } 

или с использованием диапазона проверяется подфункции, чтобы вернуть содержание:

int neighbour_value(int i, int j){ 
    if (i<0 || i>99) return 0;  /* out of range, never set */ 
    if (j<0 || j>99) return 0;  /* out of range, never set */ 
    return A[i,j]; 
} 

, а затем просто проверить с помощью

{ 
    int count = 0; 
    if(neighbour_value(i-1,j-1)==1) count++; 
    if(neighbour_value(i-1,j )==1) count++; 
    if(neighbour_value(i-1,j+1)==1) count++; 
    if(neighbour_value(i ,j-1)==1) count++; 
    if(neighbour_value(i ,j+1)==1) count++; 
    if(neighbour_value(i+1,j-1)==1) count++; 
    if(neighbour_value(i+1,j )==1) count++; 
    if(neighbour_value(i+1,j-1)==1) count++; 

    return count; 
} 
Смежные вопросы