Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 265
programmer Avatar asked Nov 16 '12 18:11

programmer


People also ask

Is multi threading possible in C?

Can we write multithreading programs in C? Unlike Java, multithreading is not supported by the language standard. POSIX Threads (or Pthreads) is a POSIX standard for threads. Implementation of pthread is available with gcc compiler.

Can multiple threads write to the same array?

The answer is no. Each array element has a region of memory reserved for it alone within the region attributed the overall array. Modifications of different elements therefore do not write to any of the same memory locations.

Can multiple threads run the same function?

A thread can execute a function in parallel with other threads. Each thread shares the same code, data, and files while they have their own stack and registers.

Can you have multiple threads?

Multithreading is a model of program execution that allows for multiple threads to be created within a process, executing independently but concurrently sharing process resources. Depending on the hardware, threads can run fully parallel if they are distributed to their own CPU core.


2 Answers

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);
}
like image 87
Sergey Kalinichenko Avatar answered Nov 08 '22 08:11

Sergey Kalinichenko


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.

like image 44
Johnny Mopp Avatar answered Nov 08 '22 07:11

Johnny Mopp