我一直遇到这个并行矩阵乘法代码的问题,在尝试访问我的结构中的数据成员时,我一直收到错误。
这是我的主要功能:
struct arg_struct
{
int* arg1;
int* arg2;
int arg3;
int* arg4;
};
int main()
{
pthread_t allthreads[4];
int A [N*N];
int B [N*N];
int C [N*N];
randomMatrix(A);
randomMatrix(B);
printMatrix(A);
printMatrix(B);
struct arg_struct *args = (arg_struct*)malloc(sizeof(struct arg_struct));
args.arg1 = A;
args.arg2 = B;
int x;
for (int i = 0; i < 4; i++)
{
args.arg3 = i;
args.arg4 = C;
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)args);
if(x!=0)
exit(1);
}
return 0;
}
和另一个C文件中使用的matrixMultiplication方法:
void *matrixMultiplication(void* arguments)
{
struct arg_struct* args = (struct arg_struct*) arguments;
int block = args.arg3;
int* A = args.arg1;
int* B = args.arg2;
int* C = args->arg4;
free(args);
int startln = getStartLineFromBlock(block);
int startcol = getStartColumnFromBlock(block);
for (int i = startln; i < startln+(N/2); i++)
{
for (int j = startcol; j < startcol+(N/2); j++)
{
setMatrixValue(C,0,i,j);
for(int k = 0; k < N; k++)
{
C[i*N+j] += (getMatrixValue(A,i,k) * getMatrixValue(B,k,j));
usleep(1);
}
}
}
}
我得到的另一个错误是创建线程:“从'void()(int ,int *,int,int *)'无效转换为'void *() (void )'[-fpermissive] “
有谁能告诉我我做错了什么?
答案 0 :(得分:4)
首先你非常糟糕地混合使用C和C ++,要么使用普通的C,要么使用C ++,在C ++中你只需使用new
和delete
。
但是你错误的原因是你在一个地方分配arg_struct
并在4个线程中释放它。您应该为每个线程分配一个arg_struct
答案 1 :(得分:1)
Big Boss是正确的,因为他已经确定了问题,但是要添加/补充他所做的回复。
选项1: 只需在循环中创建一个arg_struct并设置成员,然后将其传递给:
for(...)
{
struct arg_struct *args = (arg_struct*)malloc(sizeof(struct arg_struct));
args->arg1 = A;
args->arg2 = B; //set up args as now...
...
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)args);
....
}
将free
调用保留在线程中,但现在您可以直接使用传递的结构,而不是在线程中创建本地。
选项2: 看起来你想要从结构内部将params复制到线程,所以你不需要动态分配。
只需创建一个arg_struct并设置成员,然后将其传递给:
arg_struct args;
//set up args as now...
for(...)
{
...
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)&args);
}
然后移除free
来电。
然而,正如James指出的那样,你需要在结构的线程/父级中进行同步,以确保它没有被更改。这意味着Mutex或其他一些机制。因此,可能更容易开始将分配移动到for循环。
第2部分:
我正在使用windows(所以我当前无法进行实验),但是pthread_create param 3指的是线程函数matrixMultiplication,它被定义为void* matrixMultiplication( void* );
- 它对我来说是正确的(签名方式)来自该手册在线,void* fn (void* )
我想我必须在第二次错误时推迟给别人。这篇文章是一个comunnity wiki条目,所以如果需要可以回答这个问题。
答案 2 :(得分:1)
我不清楚你要做什么。你开始一些线程,
然后你从main
返回(退出流程),然后再获取任何内容
他们的结果。
在这种情况下,我可能不直接使用任何动态分配。
(我会使用std::vector
作为矩阵,它将使用动态
内部分配。)没有理由动态分配
arg_struct
,因为它可以安全地复制。当然,你必须这样做
等到每个线程成功提取其数据之前
循环以构造下一个线程。这通常是使用
条件:新线程一旦有条件就会解除阻塞条件
从arg_struct
中提取了论据(或者更好,你可以
使用boost::thread
,为你做这部分)。或者,你
可以使用arg_struct
的数组,但绝对没有理由
动态分配它们。 (如果由于某种原因你不能使用
对于std::vector
,A
和B
C
,您将想要分配这些
动态地,以避免任何堆栈溢出的风险。但
std::vector
是一个更好的解决方案。)
最后,当然,您必须等待所有线程完成
在离开main
之前。否则,线程将继续工作
不再存在的数据。在这种情况下,你应该
退出pthread_join
之前的所有线程main
。想必,
你也想对乘法的结果做些什么,
但无论如何,在所有线程完成之前退出main
访问矩阵将导致不确定的行为。