sbadams
sbadams

Reputation: 183

Using pthreads to process sections of an array/vector

Assume we have an array or vector of length 256(can be more or less) and the number of pthreads to generate to be 4(can be more or less).

I need to figure out how to assign each pthread to a process a section of the vector.

So the following code dispatches the multiple threads.

for(int i = 0; i < thread_count; i++)
{
    int *arg = (int *) malloc(sizeof(*arg));
    *arg = i;
    thread_err = pthread_create(&(threads[i]), NULL, &multiThread_Handler, arg);

    if (thread_err != 0)
                printf("\nCan't create thread :[%s]", strerror(thread_err));
}

As you can tell from the above code, each thread passes an argument value to the starting function. Where in the case of the four threads, the argument values range from 0 to 3, 5 threads = 0 to 4, and so forth.

Now the starting function does the following:

void* multiThread_Handler(void *arg)
{
   int thread_index = *((int *)arg);

   unsigned int start_index = (thread_index*(list_size/thread_count));
   unsigned int end_index = ((thread_index+1)*(list_size/thread_count));

   std::cout << "Start Index: " << start_index << std::endl;
   std::cout << "End Index: " << end_index << std::endl;
   std::cout << "i: " << thread_index << std::endl;

   for(int i =  start_index; i < end_index;  i++)
   {
      std::cout <<"Processing array element at: " << i << std::endl;
   }

}

So in the above code, the thread whose argument is 0 should process the section 0 - 63(in the case of an array size of 256 and a thread count of 4), the thread whose argument is 1 should process the section 64 - 127, and so forth. The last thread processing 192 - 256.

Each of these four sections should processed in parallel.

Also, the pthread_join() functions are present in the original main code to make sure each thread finishes before the main thread terminates.

The problem is, that the value i in the above for-loop is taking on suspiciously large values. I'm not sure why this would occur since I am fairly new to pthreads.

It seems like sometimes it works perfectly fine and other times and other times, the value of i becomes so large that it causes the program to either abort or presents a segmentation fault.

Upvotes: 2

Views: 2261

Answers (2)

Alexey Kukanov
Alexey Kukanov

Reputation: 12784

The problem is indeed a data race caused by lack of synchronization. And the shared variable being used (and modified) by multiple threads is std::cout.

When using streams such as std::cout concurrently, you need to synchronize all operations with a stream by a mutex. Otherwise, depending on the platform and your luck, you might get output from multiple threads messed together (which might sometimes look like printed values being larger than you expect), or you might get the program crashed, or have other sorts of undefined behavior.

Upvotes: 3

Mantosh Kumar
Mantosh Kumar

Reputation: 5741

   // Incorrect Code
   unsigned int start_index = (thread_index*(list_size/thread_count));
   unsigned int end_index = ((thread_index+1)*(list_size/thread_count));

The above code is critical region is wrong in your above program. as there is no synchronization mechanism has been used so there is data race.This leads to the wrong calculation of start_index and end_index counters and hence we may get wrong(random garbage values) and hence the for loop variable "i" goes on the toss. So you should use the following code to synchronize the critical region of your program.

   // Correct Code
   s=thread_mutex_lock (&mutexhandle);
   start_index = (thread_index*(list_size/thread_count));
   end_index = ((thread_index+1)*(list_size/thread_count));
   s=thread_mutex_unlock (&mutexhandle);

Upvotes: 0

Related Questions