سؤال

When I use the pthread_join(), I am not sure if it is in the right spot. As it is now, would it wait for the thread to exit before iterating through the loop again? I guess what I am asking is should I take it out of the double for loop and create a new for loop directly after just for the pthread_join()?

PS: I am very new to threads in general and the C language. I also have another question on freeing malloc stuff (in the code as comments). I am not sure where to use the free keyword since the malloc result pointer is gone after each iteration of the inside for loop.

Here is my code. It is for a matrix multiplication on two predefined matrices (A&B). (This is how the teacher wanted us to do it).

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

#define M 3 
#define K 2  
#define N 3 

int A[M][K] = {{1,4}, {2,5}, {3,6}}; 
int B[K][N] =  {{8,7,6}, {5,4,3}}; 
int C[M][N]; 

struct coords 
{ 
    int  i ;  /*  row  */       
    int  j ;  /*  column  */ 
}; 

//thread function
void* calc_val(void* resultCoords)
{
    int n, result = 0;
    struct coords **matCoords = (struct coords**) resultCoords;
    for(n = 0; n < K; n++)
    {
        result += A[(*matCoords)->i][n] * B[n][(*matCoords)->j];
    }
    C[(*matCoords)->i][(*matCoords)->j] = result;
    // One more question: 
    // <- Should I free mem from malloc here? 
}

int main(int argc, char** argv) 
{
    int numThreads = M * N, threadIndex = 0, i, j;
    pthread_t threads[numThreads];
    pthread_attr_t attributes[numThreads];
    for (i = 0; i < M; i++)
    {
        for(j = 0; j < N; j++)
        {
            struct coords *data = (struct coords*)malloc(sizeof(struct coords));
            data->i = i;
            data->j = j;
            pthread_attr_init(&attributes[threadIndex]);
            pthread_create(
                    &threads[threadIndex],
                    &attributes[threadIndex],
                    calc_val, 
                    &data);
            pthread_join(threads[threadIndex], NULL); // <-Main Question
            threadIndex++;
        }
    }

    /* ... */

    return (EXIT_SUCCESS);
}
هل كانت مفيدة؟

المحلول

In your code you basically do following:

  1. prepare some data for thread
  2. run thread
  3. wait till it finished
  4. go to next iteration

so this code it absolutely sequential

to make it non sequential you need something like this:

  1. prepare some data
  2. run thread
  3. go to next iteration
  4. wait until all threads are finished

try something like this:

   for (i = 0; i < M; i++)
   {
        for(j = 0; j < N; j++)
        {
            struct coords *data = (struct coords*)malloc(sizeof(struct coords));
            data->i = i;
            data->j = j;
            pthread_attr_init(&attributes[threadIndex]);
            pthread_create(&threads[threadIndex], &attributes[threadIndex], calc_val, &data);
            threadIndex++;
        }
    }
    for (i=0;i<numThreads;i++)
        pthread_join(threads[i], NULL);

next problem about memory allocation - you can do it either when all threads are finished (then you need to store somewhere all allocated pointers), or you can just free in it each thread as you asked in comments

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top