介绍 线程是操作系统能够进行运算调度的最小单位 。它被包含在进程之中,是进程中的实际运作单位。在这个实验中,我们要充分利用多线程的优点,将复杂的任务细分为多个简单的任务,利用分治 的思想解决复杂而庞大的问题。本实验包含两个问题:
内容1 分析 使用多线程生成Fibonacci数列,最后在进程中打印数列结果。 关于多线程编程的主要系统调用:
pthread_create()
:创建线程。第一个参数是&pid(pid为线程号),第二个参数为&attr(attr为线程初始化的属性),第三个参数是执行的方法的指针*runner(即该线程调用名为runner的函数),第四个参数是¶(传入runner的参数)。
pthread_join()
:阻塞调用线程,直到threadid所指定的线程终止。每个线程只能用pthread_join()一次。若多次调用就会发生逻辑错误。
pthread_exit()
:终止调用线程。
pthread_attr_init()
:初始化线程属性为默认属性。
pthread_attr_getscope()
:获得线程竞争范围。
pthread_attr_setscope()
:设置线程竞争范围。
代码实现 生成Fibonacci数列本身的原理很简单,需要注意数列前两项需要手动初始化,其后的每一项都可以通过循环来求得。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <pthread.h> #include <stdio.h> int fib_arr[1000 ] = {0 };void *runner (void *param) ; int size;int main (int argc, char *argv[]) { printf ("Please enter a number: " ); scanf ("%d" , &size); while (size < 2 ) { printf ("Invalid number!!\n" ); printf ("Please enter a number: " ); scanf ("%d" , &size); } fib_arr[0 ] = 0 ; fib_arr[1 ] = 1 ; pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); pthread_create(&tid, &attr, runner, &fib_arr); pthread_join(tid, NULL ); for (int i = 0 ; i <= size; i++) { printf ("fib_arr[%d] = %d\n" , i, fib_arr[i]); } return 0 ; } void *runner (void *param) { int *temp = (int *) param; for (int i = 2 ; i <= size; i++) { temp[i] = temp[i-1 ] + temp[i-2 ]; } pthread_exit(0 ); }
编译执行上述代码,结果如下:
内容2 分析 使用多线程来解决两个矩阵的乘法问题。给出矩阵A、B,求解C。对于C的每一个元素,我们都创建一个进程来求解。进程的创建、调用等与内容1类似。这里特别注意,由于我们传入的参数是一个坐标,因此需要自定义一个结构 存放两个int类型的数据。
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #define M 3 #define K 2 #define N 3 #define NUM_THREADS 10 int A[M][K] = {{1 ,4 }, {2 ,5 }, {3 ,6 }};int B[K][N] = {{8 ,7 ,6 }, {5 ,4 ,3 }};int C[M][N] = {0 };struct v { int i; int j; }; void *runner (void *param) ; int main () { pthread_t workers[M*N]; pthread_attr_t attr; pthread_attr_init(&attr); 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(&workers[i*N + j], &attr, runner, (void *)data); } } for (int i = 0 ; i < M*N; i++) { pthread_join(workers[i], NULL ); } for (int i = 0 ; i < M; i++) { for (int j = 0 ; j < N; j++) { printf ("%d " , C[i][j]); } printf ("\n" ); } return 0 ; } void *runner (void *param) { struct v *temp = (struct v*)param; int i = temp->i; int j = temp->j; for (int n = 0 ; n < K; n++) { C[i][j] += A[i][n]*B[n][j]; } pthread_exit(0 ); }
编译并执行上述代码,结果如下: 有兴趣的朋友可以自己改进代码,添加用户输入矩阵的功能。
小结 这个实验通过两个例子,使用了多线程的编程去求解复杂的问题。通过这个实现,我们学会了如何创建并调用线程,如何传递参数等。关于多线程的实验就分享到这里了,谢谢!