User Tools

Site Tools


c:pthreads:mutex-barrier-array-sum

Compute the sum of an array elements in parallel using pthread with mutex and barrier

pthread-mutex-barrrier-sum-array.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
 
#define NUM_THREADS 4  // Number of threads
#define ARRAY_SIZE 100  // Size of the array
 
int array[ARRAY_SIZE];
int total_sum = 0;
pthread_mutex_t sum_mutex;
pthread_barrier_t sum_barrier;
 
// Function for each thread to compute part of the sum
void *partial_sum(void *arg) {
    int thread_part = *(int*)arg;
    int local_sum = 0;
 
    // Calculate partial sum for this thread's part of the array
    for(int i = thread_part * (ARRAY_SIZE / NUM_THREADS); i < (thread_part + 1) * (ARRAY_SIZE / NUM_THREADS); i++) {
        local_sum += array[i];
    }
 
    // Wait at the barrier for all threads to finish their part
    pthread_barrier_wait(&sum_barrier);
 
    // Only one thread at a time updates the total sum
    pthread_mutex_lock(&sum_mutex);
    total_sum += local_sum;
    pthread_mutex_unlock(&sum_mutex);
 
    pthread_exit(NULL);
}
 
int main() {
    pthread_t threads[NUM_THREADS];
    int thread_args[NUM_THREADS];
    int status;
 
    // Initialize array with some values
    for(int i = 0; i < ARRAY_SIZE; i++) {
        array[i] = i + 1;  // Fill the array with numbers 1 to 100
    }
 
    // Initialize mutex and barrier
    pthread_mutex_init(&sum_mutex, NULL);
    pthread_barrier_init(&sum_barrier, NULL, NUM_THREADS);
 
    // Create threads
    for(int i = 0; i < NUM_THREADS; i++) {
        thread_args[i] = i;
        status = pthread_create(&threads[i], NULL, partial_sum, (void *)&thread_args[i]);
 
        if (status != 0) {
            printf("ERROR; return code from pthread_create() is %d\n", status);
            exit(-1);
        }
    }
 
    // Wait for all threads to complete
    for(int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
 
    // Print the total sum
    printf("Total sum is: %d\n", total_sum);
 
    // Clean up and exit
    pthread_mutex_destroy(&sum_mutex);
    pthread_barrier_destroy(&sum_barrier);
 
    return 0;
}

Each thread computes a partial sum of a portion of the array. After computing their part, threads synchronize at a barrier. Once all threads reach the barrier, they proceed to update the total sum using a mutex for safe access.

Array and Variables: An array array is initialized with values. A global variable total_sum stores the total sum, and a mutex sum_mutex is used for safe updating of this sum.

Thread Function (partial_sum): Each thread computes a partial sum for its portion of the array. Then, it waits at a barrier using pthread_barrier_wait. After all threads reach the barrier, they update total_sum protected by a mutex.

Main Function: Initializes the array, mutex, and barrier. Creates NUM_THREADS threads, each executing partial_sum. Finally, it waits for all threads to complete, prints the total sum, and cleans up.

This approach ensures that each segment of the array is processed in parallel by different threads, and the total sum is updated in a thread-safe manner.
The use of the barrier guarantees that all threads have finished calculating their partial sums before starting to update the total sum, thus avoiding race conditions and ensuring data consistency.

c/pthreads/mutex-barrier-array-sum.txt · Last modified: 2024/01/17 00:24 by odefta