使用Windows API 编写按行分配的计算矩阵向量相乘的并行程序

  水了一学期的院选修,万万没想到期末考试还有比较硬核的编程题,居然还涉及到多线程了,而且是调用Windows接口函数写多线程。虽然学汇编的时候有所了解,但毕竟没尝试过,思来想去,写出了下面的蹩脚代码,不足之处还望各位批评指正。题目描述如下:

  采用windows接口函数,编写一个计算矩阵向量相乘的并行程序,矩阵按行划分后分别散发到不同的线程中,向量被复制到各个线程中,程序执行结束时,由主线程输出结果向量。假设矩阵定义为浮点型数组A[64][64],向量定义为浮点型数组y[64],结果向量存放到浮点型数组z[64]中,所用处理器有8个计算核。

  开始分析:如果把矩阵按行分配给不同线程的话,很明显每个线程应该被分配八行。由于对不同行的矩阵进行操作不会发生冲突,所以连线程的同步机制都用不到,就是简单的编写一个计算矩阵向量相乘的线程函数,然后创建多个线程执行就可以了。代码实现如下

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 double z[64];    //结果向量 
 5 double y[64];    //待乘向量 
 6 double A[64][64];//待乘矩阵 
 7 const int numThreads = 8;//线程数
 8 
 9 DWORD WINAPI threadFunction(LPVOID pArg) {
10     int myNum = *((int *)pArg); //获取本线程所需参数
11     int n = myNum + 8;             //设置外层循环上界 
12     for(int i = myNum; i < n; ++i){//相乘计算的具体步骤 
13         for(int j = 0; j < 64; ++j)
14             z[i] += A[i][j] * y[i]; 
15     }
16     return 0;
17 }
18 
19 int main() {
20     HANDLE threadHandles[numThreads];//线程数组
21     int tNum[numThreads];//用于传给线程的参数数组
22     
23     printf("请输入矩阵:\n");
24     for(int i = 0; i < 64; ++i)
25         for(int j = 0; j < 64; ++j)
26             scanf("%lf", &A[i][j]); 
27             
28     printf("请输入向量:\n");
29     for(int i = 0; i < 64; ++i)
30         scanf("%lf", &y[i]); 
31         
32     printf("相乘后的结果向量为: \n");
33 
34     for(int i = 0; i < numThreads; ++i) {
35         tNum[i] = i * 8;    //给传给线程的参数赋值 
36         threadHandles[i] = CreateThread( NULL,            // 安全属性 
37                                          0,               // 栈大小
38                                          threadFunction,  // 传给线程的函数 
39                                          (LPVOID)&tNum[i],// 传给线程的参数 
40                                          0,               // 线程创建后立即激活
41                                          NULL);           // 新线程的id会被传给这个参数所在的变量
42     }
43     WaitForMultipleObjects( numThreads,        // 等待的线程数 
44                             threadHandles,     // 等待的线程数组 
45                             TRUE,              // 等待所有信号量有效在往下执行      
46                             INFINITE);         // 表示无穷等待
47     for(int i = 0; i < 64; ++i) //输出结果向量 
48         printf("%.2lf ", z[i]);
49     return 0;
50 }

  至此,已经解决问题了。还好题目要求不是特别难,也算是通过一段代码初步了解如何使用Windows接口函数编写多线程了。不得不说C语言确实强大,可惜我基础不扎实加上现在又忘得差不多了,写这段代码时居然想通过scanf("%f",&变量名来输入double类型的值,迟迟得不到预期结果。我还以为是多线程惹的祸,得亏调试了一下才知道原来我连值都没有正确输进去,double类型的输入格式必须是%lf,输出的话%f%lf均可,学到了学到了。只有犯错了才能学的更透彻啊😭

posted @ 2020-06-20 10:58  小柒w  阅读(485)  评论(0编辑  收藏  举报