简体   繁体   English

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

[英]How to use thread pool and message queues in Multithreaded Matrix Multiplication?

I'm trying to learn multithreading by doing a multithreaded matrix multiplication program.I'm computing one row at a time. 我正在尝试通过编写多线程矩阵乘法程序来学习多线程。我一次只计算一行。 I am facing problem when I am using fewer threads than the rows. 当我使用的线程少于行时,我遇到了问题。 I read lot of similar posts but could not understand clearly how can I reuse them. 我阅读了很多类似的文章,但不清楚地我该如何重复使用它们。 But there are two possible methods. 但是有两种可能的方法。

  1. Using a thread pool and making a task queue- I did not understand after completion of task , how the next task is assigned to a particular thread among pool of threads 使用线程池并创建任务队列-任务完成后,我不了解,下一个任务如何分配给线程池中的特定线程

  2. message queues. 消息队列。

How do I use mutex lock on shared variable sum? 如何在共享变量总和上使用互斥锁?

Please suggest me possible changes I should add in following program. 请建议我应该在以下程序中添加的可能更改。

#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 ?
}

Any help will be appreciated! 任何帮助将不胜感激!

How do I use mutex lock on shared variable sum? 如何在共享变量总和上使用互斥锁?

You need to declare a mutex and use it to lock the sum before use sum ,and unlock it after use sum. 您需要声明一个mutex lock ,并在使用sum之前使用它来lock sum,并在使用sum之后unlockunlock Do that every time you use sum to protect it. 每次使用sum来保护它时,都要这样做。

Here is a example : 这是一个例子:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&lock);

use sum ....

pthread_mutex_unlock(&lock);

You can reuse a pthread attribute to create more then one thread. 您可以重用pthread属性来创建多个线程。 Also it needs to be destroyed to free any resources used. 此外,还需要销毁它以释放所使用的任何资源。

Also to allow the threads to run in parallel first create them all and then join them: 另外,要允许线程并行运行,请先创建所有线程, 然后将它们加入:

  ... 

  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);
  }

  ...

As a final note: Error checking is ommitted in the example lines above. 最后一点:上面的示例行中省略了错误检查。 But for any "real" code always check the outcome of a system call. 但是对于任何“真实”代码,请始终检查系统调用的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM