programmer
programmer

Reputation: 4921

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

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

Upvotes: 5

Views: 37640

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727027

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

Upvotes: 6

001
001

Reputation: 13533

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.

Upvotes: 3

Related Questions