How can i have multiple threads in C working on the same for loop of a two-dimensional array?

34,400

Solution 1

You should create an array of per-thread parameters, and pass these to the threads one-by-one. In your case a single pointer to int is sufficient: you pass to the thread its index threadindex from zero to NTHREADS, and the thread passes back the sum for rows such that row % NTHREADS == threadindex.

Here is how your thread function looks:

void *CalculateSum(void *args)
{
    int *argPtr = args;

    int i,j,sum = 0;
    int threadindex = *argPtr;

    for( i = 0; i <= N-1; i++) {
        if (i % NTHREADS != threadindex) continue;
        for( j = 0; j <= M-1; j++) {
            sum += dimensional_array[i][j];
        }
    }

    pthread_mutex_lock( &mutex1 ); Mutex must go here
    counter++;
    pthread_mutex_unlock( &mutex1 );
    // Pass the value back:
    *argPtr = sum;
}


main()
{
    pthread_t thread_id[NTHREADS];
    int thread_args[NTHREADS];
    int i, j;

    pthread_mutex_init(&mutex1, NULL);

    for (i = 0; i <= N - 1; i++ )
        for( j = 0; j <= M - 1; j++)
            dimensional_array[i][j] = i;

    for(i=0; i < NTHREADS; i++)
    {
        thread_args[i] = i;
        pthread_create( &thread_id[i], NULL, CalculateSum, &thread_args[i]);
    }

    int sum = 0;
    for(j=0; j < NTHREADS; j++)
    {
        pthread_join( thread_id[j], NULL);
        sum += thread_args[i];
    }

    printf("Final counter value: %d. Total: %d\n", counter, sum);
}

Solution 2

To calc the sum of one line (ignoring the thread stuff):

void *CalculateSum(void *dummyPtr)
{
    int j,sum = 0;

    int i = (int)dummyPtr;
    for( j = 0; j <= M-1; j++) {
        sum += dimensional_array[i][j];
    }
    printf(" Sum = %d\n", sum);

    pthread_mutex_lock( &mutex1 );
    counter++;
    pthread_mutex_unlock( &mutex1 );
}

And then create the thread like this:

int line_number = 2;    // Or whatever line to print`enter code here`
pthread_create( &thread_id[i], NULL, CalculateSum, (void *)line_number );

EDIT: put "counter++" back in.

Share:
34,400
programmer
Author by

programmer

Updated on November 17, 2020

Comments

  • programmer
    programmer over 3 years

    i have a program in C.

    I have created 3 threads with pthread_create and i have created a mutex in order to lock/unlock the critical regions.

    The 3nd argument of pthread_create is a pointer to a function that the thread will execute.

    In the examples i've found in the Web, this function is always very simple e.g. prints the thread id or prints a message.

    What happens when the function that the thread shall execute contains a for loop?

    Cause in my program i would like each one of the threads to work with a two dimensional array.

    Each thread shall find the sum of a line of a two-dimensional array. e.g.

    Thread1 shall calculate the sum of first line of the 2-dimensional array

    Thread2 shall calculate the sum of the second line
    Thread1 shall calculate the sum of the 3nd line
    Thread3 shall calculate the sum of the 3nd line

    I don't care about the order of the threads, but i need every thread to pick one of the lines.

    I have the following code that sums two cells in the two dimensional array.

    The program:

    1. creates NTHREADS

       for(i=0; i < NTHREADS; i++)
          {
             pthread_create( &thread_id[i], NULL, CalculateSum, NULL );
          }
      
    2. Each thread waits for the others to finish

      for(j=0; j < NTHREADS; j++)
         {
            pthread_join( thread_id[j], NULL);
         }
      
    3. the function that each thread shall execute but for ONE line of the array and NOT for the WHOLE array is

      void *CalculateSum(void *dummyPtr)
      {
         pthread_mutex_lock( &mutex1 );
      
       int i,j,sum = 0;
      
        for( i = 0; i <= N-1; i++) {
              for( j = 0; j <= M-1; j++) {
                      sum = dimensional_array[i][j] + dimensional_array[i][j];
              }
               printf(" Sum = %d\n", sum);
              }
      
         counter++;
      
         pthread_mutex_unlock( &mutex1 );
      }
      

    The whole program is as follows: The program does not have any compilation error.

    In order to run it you shall do: gcc -pthread program.c

        //program.c
    
       #include <stdio.h>
       #include <pthread.h>
    
       #define NTHREADS 3
       void *CalculateSum(void *);
       pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
       int  counter = 0;
    
       #define N 10
       #define M 10
    
       int dimensional_array[N][M];
    
       main()
       {
          pthread_t thread_id[NTHREADS];
          int i, j;
    
          for (i = 0; i <= N - 1; i++ )
               for( j = 0; j <= M - 1; j++)
                       dimensional_array[i][j] = i;
    
          for(i=0; i < NTHREADS; i++)
          {
             pthread_create( &thread_id[i], NULL, CalculateSum, NULL );
          }
    
          for(j=0; j < NTHREADS; j++)
          {
             pthread_join( thread_id[j], NULL);
          }
    
    
    
          printf("Final counter value: %d\n", counter);
    
          //print ARRAY
          for (i = 0; i <= N-1; i++ ) {
               for( j = 0; j <= M-1; j++)
                       printf("%d\t",dimensional_array[i][j]);
               printf("\n");
               }
       }
       //Calculate
       void *CalculateSum(void *dummyPtr)
       {
          pthread_mutex_lock( &mutex1 );
    
        int i,j,sum = 0;
    
         for( i = 0; i <= N-1; i++) {
               for( j = 0; j <= M-1; j++) {
                       sum = dimensional_array[i][j] + dimensional_array[i][j];
               }
                printf(" Sum = %d\n", sum);
               }
    
          counter++;
    
          pthread_mutex_unlock( &mutex1 );
       }
    

    So, i would like each thread to find the sum of a line but i'm confused, i don't know how to do that.

    In my program every time a thread calls the Calculate function, all the sum of the lines are computed and not just one

    [Caution:For simplicity i sum the first element with it's own,the point is to understand how those threads can all take place in that for loop]

    I would be glad if someone could help me

    Thanks, in advance

  • MattJenko
    MattJenko over 11 years
    This was going to be my answer, but I think (correct me if I'm wrong) that because each thread is only reading the array then you actually don't need the mutex - making the program run 3 times as fast on a multi-core processor :)
  • Johnny Mopp
    Johnny Mopp over 11 years
    Yes, I see no need for the mutex either, but apparently it's part of OPs assignment.
  • Johnny Mopp
    Johnny Mopp over 11 years
    After re-checking it looks like it's there to access the global "counter" variable which I left out.
  • MattJenko
    MattJenko over 11 years
    Ah yes, I see now. With the 'counter' variable you most definitely do - did you want to put that in @Johnny
  • programmer
    programmer over 11 years
    I have a problem with the int threadindex argPtr; , i get an error like program.c: In function 'CalculateSum': program.c:23: error: expected '=', ',', ';', 'asm' or 'attribute' before '' token program.c:26: error: 'threadindex' undeclared (first use in this function) program.c:26: error: (Each undeclared identifier is reported only once program.c:26: error: for each function it appears in.)
  • Sergey Kalinichenko
    Sergey Kalinichenko over 11 years
    @programmer Yes, a = was indeed missing there.