我编写了一个执行两个矩阵相乘的程序。当我执行它时,它有时会工作,有时它不起作用,有时一半的答案是正确的。我认为线程和信号量的使用存在问题。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <mutex>
#include <thread>
//NOTE: THIS CODE NEEDS C++11 COMPILER TO COMPILE.
using namespace std;
int const size = 4;
mutex mtx[size][size];
thread myThread[size];
void MatrixMultiplication(int const * const * matrixA, int const * const * matrixB,int** matrixC, int row, int col, int i){
mtx[row][col].lock();
matrixC[row][col] += matrixA[row][i]*matrixB[i][col];
mtx[row][col].unlock();
}
int main()
{
int** matrixA;
int** matrixB;
int** matrixC;
matrixA = new int*[size];
matrixB = new int*[size];
matrixC = new int*[size];
for(int i = 0; i<size; i++){
matrixA[i] = new int[size];
matrixB[i] = new int[size];
matrixC[i] = new int[size];
}
//WE ARE INITIALIZING MATRICES.
int count = 1;
for(int i = 0; i<size; i++){
for(int j = 0; j<size; j++){
matrixA[i][j] = count;
matrixB[i][j] = count;
count++;
}
}
for(int row=0; row<size; row++){
for(int col=0; col<size;col++){
for(int i=0;i<size;i++){
myThread[i] = thread(MatrixMultiplication, matrixA, matrixB, matrixC, row, col, i);
myThread[i].join();
}
}
}
for(int i = 0; i<size; i++){
for(int j = 0; j<size; j++){
cout<<matrixC[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
答案 0 :(得分:1)
据我所知,这里有两件事情出了问题。
for(int row=0; row<size; row++){
for(int col=0; col<size;col++){
for(int i=0;i<size;i++){
myThread[i] = thread(MatrixMultiplication, matrixA, matrixB, matrixC, row, col, i);
myThread[i].join();
}
}
}
应该是
for(int row=0; row<size; row++){
for(int col=0; col<size;col++){
for(int i=0;i<size;i++){
myThread[i] = thread(MatrixMultiplication, matrixA, matrixB, matrixC, row, col, i);
}
}
}
for(int row=0; row<size; row++){
for(int col=0; col<size;col++){
for(int i=0;i<size;i++){
myThread[i].join();
}
}
}
这样你首先要创建一堆计算。然后进行实际计算。然而,这仍然不是你应该采取的方式。一个帖子应该有合理的工作量。
所以在你继续这样做之前,请允许我解释一下线程。一个线程同时执行不同的工作 。由于它是在同一时间执行的,因此您永远不能让线程访问可能由另一个线程写入的数据。否则,你可能会得到一半写入的数据(所谓的竞争条件)。
因此,std::thread()
调用将始终复制它给出的所有参数。即使它是一个指针。你可以做的是让每个线程在一个单独的线程上为每一列进行计算。但是,为了做到这一点,我建议创建一个column
结构或类。并通过std::ref
传递给线程。使用std::ref
传递将阻止数据被复制。