panos3p
panos3p

Reputation: 13

multithreaded game of life in c

I 've been trying to implement a multithreaded game of life in c. The program reads a 2d array(A[100][100]) sized 100x100 from a file, copies that into a second array(B[100][100]) and creates 100 threads which are assigned a 10x10 part of the array and the threads are supposed to check each cell's neighbours(from array A) and change it's status according to the rules, in array B, when they 're finished the main function copies B into A and starts aggain from the beggining until the user stops the program. My problem is that the threads only change values for the last part of the array(positions [90-99][90-99]). does anyone have any idea as to might be going wrong?(if I use the same code but assign the whole array to all of the threads the output is correct, the same happens if I only use one thread)

Upvotes: 1

Views: 1661

Answers (2)

Tommylee2k
Tommylee2k

Reputation: 2731

your "has_neighbors" as a whole lot of redundant code, which could be removed with either combining the rangechecks with the content check,

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

or by using a range checked subfunction to return the content:

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

and then just check via

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

Upvotes: 0

001
001

Reputation: 13533

Here:

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

You're passing the same array to each thread. So all threads will have the same parameters - whatever the final values of c are at the end of the loops.

Instead, give each thread it's own 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);
    }
}

Upvotes: 2

Related Questions