c中的多线程生活游戏
multithreaded game of life in c
我一直在尝试用 c 实现一个多线程的生活游戏。该程序从文件中读取大小为 100x100 的二维数组 (A[100][100]),将其复制到第二个数组 (B[100][100]) 中并创建 100 个线程,这些线程分配了数组的 10x10 部分,并且线程应该检查每个单元格的邻居(来自数组 A)并根据规则更改它的状态,在数组 B 中,当它们完成时,主函数将 B 复制到 A 并从开始重新开始,直到用户停止程序。我的问题是线程只更改数组最后一部分的值(位置 [90-99][90-99])。有没有人知道可能会出错?(如果我使用相同的代码但将整个数组分配给所有线程输出是正确的,如果我只使用一个线程也会发生同样的情况)
这里:
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);
}
}
你的 "has_neighbors" 是一大堆冗余代码,可以通过将范围检查与内容检查相结合来删除,
...
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;
}
或使用范围检查子函数 return 内容:
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;
}
我一直在尝试用 c 实现一个多线程的生活游戏。该程序从文件中读取大小为 100x100 的二维数组 (A[100][100]),将其复制到第二个数组 (B[100][100]) 中并创建 100 个线程,这些线程分配了数组的 10x10 部分,并且线程应该检查每个单元格的邻居(来自数组 A)并根据规则更改它的状态,在数组 B 中,当它们完成时,主函数将 B 复制到 A 并从开始重新开始,直到用户停止程序。我的问题是线程只更改数组最后一部分的值(位置 [90-99][90-99])。有没有人知道可能会出错?(如果我使用相同的代码但将整个数组分配给所有线程输出是正确的,如果我只使用一个线程也会发生同样的情况)
这里:
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);
}
}
你的 "has_neighbors" 是一大堆冗余代码,可以通过将范围检查与内容检查相结合来删除,
...
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;
}
或使用范围检查子函数 return 内容:
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;
}