如何在多线程矩阵乘法中使用线程池和消息队列?

时间:2013-08-10 10:13:17

标签: c multithreading pthreads matrix-multiplication

我正在尝试通过执行多线程矩阵乘法程序来学习多线程。我一次计算一行。当我使用比行更少的线程时,我遇到了问题。我阅读了很多类似的帖子,但无法清楚地理解我如何重用它们。但是有两种可能的方法。

  1. 使用线程池并创建任务队列 - 在完成任务后我无法理解,如何将下一个任务分配给线程池中的特定线程

  2. 消息队列。

  3. 如何在共享变量sum上使用互斥锁?

    请建议我在下面的程序中添加可能的更改。

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define M 6
    #define K 7
    #define N 8
    #define NUM_THREADS 4
    
    int A[M][K] = { { 1, 4, 8, 4, 5, 6, 2 }, { 7, 3, 2, 4, 1, 4, 5 }, { 2, 3, 9, 4,
            7, 1, 5 }, { 4, 3, 9, 4, 7, 2, 5 }, { 1, 3, 9, 9, 7, 1, 3 }, { 2, 4, 9,
            3, 7, 1, 5 } };
    int B[K][N] = { { 8, 3, 8, 4, 5, 6, 2, 3 }, { 1, 3, 2, 2, 3, 4, 8, 1 }, { 8, 3,
            9, 1, 7, 1, 5, 2 }, { 1, 3, 9, 2, 7, 2, 5, 2 },
            { 1, 3, 9, 2, 7, 1, 3, 3 }, { 2, 4, 9, 3, 7, 1, 5, 2 }, { 2, 4, 9, 3, 7,
                    1, 5, 2 } };
    int C[M][N];
    
    struct v {
        int i; /* row */
        int j; /* column */
    };
    
    void *runner(void *param); /* the thread */
    
    int main(int argc, char *argv[]) {
    
        int i, j, count = 0;
        for (i = 0; i < NUM_THREADS; i++) {
    
            //Assign a row and column for each thread
            struct v *data = (struct v *) malloc(sizeof(struct v));
            data->i = i;
            data->j = j;
            /* Now create the thread passing it data as a parameter */
            pthread_t tid[NUM_THREADS];       //Thread ID
            pthread_attr_t attr; //Set of thread attributes
            //Get the default attributes
            pthread_attr_init(&attr);
            //Create the thread
            pthread_create(&tid, &attr, runner, data);
            //Make sure the parent waits for all thread to complete
            pthread_join(tid, NULL );
            count++;
    
        }
    
        //Print out the resulting matrix
        for (i = 0; i < M; i++) {
            for (j = 0; j < N; j++) {
                printf("%d ", C[i][j]);
            }
            printf("\n");
        }
    }
    
    //The thread will begin control in this function
    void *runner(void *param) {
        struct v *data = param; // the structure that holds our data
        int n, x, sum = 0; //the counter and sum
    
        //Calculating one row
    
        for (x = 0; x < N; x++) {
            for (n = 0; n < K; n++)
    
            {
                sum += A[data->i][n] * B[n][x];
            }
            //assign the sum to its coordinate
            C[data->i][data->j] = sum;
        }
        //Exit the thread
        pthread_exit(0); // How can I reuse this thread for another row instead of exiting it ?
    }
    

    任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

如何在共享变量sum上使用互斥锁?

您需要声明mutex并使用它来lock使用总和前的总和,并在使用总和后unlock。每次使用总和来保护它时都这样做。

这是一个例子:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&lock);

use sum ....

pthread_mutex_unlock(&lock);

答案 1 :(得分:0)

您可以重用pthread属性来创建多个线程。还需要销毁它以释放所有使用的资源。

同样允许线程并行运行首先创建所有线程,然后然后加入它们:

  ... 

  pthread_attr_t attr; //Set of thread attributes
  //Get the default attributes
  pthread_attr_init(&attr);
  pthread_t tids[NUM_THREADS] = {0};
  for (i = 0; i < NUM_THREADS; i++) {

    //Assign a row and column for each thread
    struct v *data = (struct v *) malloc(sizeof(struct v));
    data->i = i;
    data->j = j;

    //Create the thread
    pthread_create(&tids[i], &attr, runner, data);
    //Make sure the parent waits for all thread to complete
    count++;
  }
  pthread_attr_destroy(&attr);

  for (i = 0; i < NUM_THREADS; i++) {
    pthread_join(tids[i], NULL);
  }

  ...

最后一点:上面的示例行中省略了错误检查。但是对于任何“真实”代码,总是检查系统调用的结果。