1

マルチスレッドの行列乗算プログラムを実行して、マルチスレッドを学習しようとしています。一度に 1 つの行を計算しています。行よりも少ないスレッドを使用しているときに問題に直面しています。同様の投稿をたくさん読みましたが、それらを再利用する方法を明確に理解できませんでした。しかし、2 つの方法が考えられます。

  1. スレッド プールを使用してタスク キューを作成する - タスクが完了した後、次のタスクがスレッドのプールの中で特定のスレッドに割り当てられる方法がわかりませんでした

  2. メッセージ キュー。

共有変数 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 ?
}

どんな助けでも大歓迎です!

4

2 に答える 2

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

  ...

最後の注意: 上記の例では、エラー チェックが省略されています。ただし、「実際の」コードについては、常にシステム コールの結果を確認してください。

于 2013-08-10T11:02:48.480 に答える