Project3:
Matrix Multiplication
一、实验环境
Ubuntu 10.04系统
Eclipse开发平台
二、实验过程:
这个实验中,分别用java、pthread实现多线程矩阵运算。
1、java实现
程序大体思路:
1、新建类WorkThread,作为Runnable的一个接口。传递的参数有,当前计算的行、列,矩阵A、B、C,以及K值,通过for循环计算C矩阵当前行、列的值。
2、main函数中
2.1 首先初始化矩阵A、B、C,常数N、M、K等
3.2 建立N*M个线程,对应计算C的对应位置
3.3 通过for循环等待线程结束,输出此位置的结果
2、pthread实现
程序大体思路:
程序思路与java实现一样,在语言、函数上进行了改变:
编写thread_function函数进行计算,通过pthread_create函数建立线程,pthread_join等待线程结束。
3、运行并测试
java:
结果如下:
28 23 18
41 34 27
54 45 36
pthread:
编译命令: gcc -O2 -Wall -o project project2.c -lpthread -std=c99
运行: ./project
结果如下:
28 23 18
41 34 27
54 45 36
4、在实验中遇到的一些问题
在pthread编程中,由于对C语言不熟悉,程序中的printf(" %d/t", (int)thread_result[i][j])语句,之前用的是printf(" %s/t", (char *)thread_result[i][j]),编译后运行总是提示段错误。让我纠结了半天。在网上查找后改正错误解决。
在pthread_join、pthread_create函数的参数的形式上我也遇到了不少问题,后来经过多次调试后改正。
pthread程序的编译命令,一开始我使用gcc –o project project2.c,遇到错误。根据提示,加上 -std=c99后,依旧没有解决。在网上各种查找后,得到编译命令:gcc -O2 -Wall -o project project2.c -lpthread -std=c99,虽然很多参数不懂是什么意思,但是编译运行成功了,也就没有深究。
java程序编写上,遇到问题较少,主要是一些基本语言问题,查询后很快解决。
三、实验总结
在这个实验中,通过多线程解决矩阵乘法问题,虽然问题相对简单,但它加深了我对线程的理解:新建、启动、结束以及在什么时候用线程等等。通过这次实验,我也对java、C语言有了一定了了解。通过java、C和C++语言的比较,我觉得java语言的类、对象操作十分简单实用,十分完美。
最后感谢助教、老师的帮助。
附:原代码如下:
pthread
#include "pthread.h"
#include "stdio.h"
#include <stdlib.h>
#define M 3
#define K 2
#define N 3
int A[M][K]={{1,4},{2,5},{3,6}};
int B[K][N]={{8,7,6},{5,4,3}};
int C[M][N];
//存放矩阵某点
struct v
{
int i;
int j;
};
// 计算C矩阵对应位置上的值
void* thread_function(void *arg)
{
struct v *tem=(struct v*) arg;
int row=tem->i;
int col=tem->j;
C[row][col]=0;
for(int t=0;t<K;t++)
{C[row][col]+=A[row][t]*B[t][col];}
pthread_exit((void *)C[row][col]);
}
int main()
{
pthread_t my_thread[M][N];
void* thread_result[M][N];
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
struct v *data=(struct v*)malloc(sizeof(struct v));
data->i=i;
data->j=j;
//新建线程
pthread_create(&my_thread[i][j],NULL,thread_function,(void*)data);
}
}
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
//等待线程结束
pthread_join(my_thread[i][j],(void *) &thread_result[i][j]);
//输出结果
printf(" %d/t", (int)thread_result[i][j]);
}
printf("/n");
}
exit(0);
}
编译及结果:
rongry@ubuntu:~/experiment$ gcc -O2 -Wall -o project project2.c -lpthread -std=c99
rongry@ubuntu:~/experiment$ ./project
28 23 18
41 34 27
54 45 36
java
//实现Runnable接口
public class WorkThread implements Runnable{
private int row;
private int col;
private int [][]A;
private int [][]B;
private int [][]C;
private int k;
public WorkThread(int row,int col,int [][]A,int [][]B,int [][]C,int k){
this.row=row;
this.col=col;
this.k=k;
this.A=A;
this.B=B;
this.C=C;
}
//计算C矩阵对应位置的值
@Override
public void run() {
// TODO Auto-generated method stub
C[row][col]=0;
for(int i=0;i<k;i++){
C[row][col]+=A[row][i]*B[i][col];
}
}
}
public class MatrixMultiplication {
final static int M = 3;
final static int K = 2;
final static int N = 3;
public static void main(String args[]) throws java.io.IOException,
InterruptedException {
int[][] A = { { 1, 4 }, { 2, 5 }, { 3, 6 } };
int[][] B = { { 8, 7, 6 }, { 5, 4, 3 } };
int[][] C ;
C=new int[M][N];
Thread[][] T ;
T=new Thread[M][N];
WorkThread[][] W;
W=new WorkThread[M][N];
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
//新建线程并启动
W[i][j] = new WorkThread(i, j, A, B, C, K);
T[i][j] = new Thread(W[i][j]);
T[i][j].start();
}
}
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
//等待线程结束
T[i][j].join();
System.out.print(C[i][j] + "/t");
}
System.out.print("/n");
}
}
}
结果:
28 23 18
41 34 27
54 45 36