How to sum an array using threading in C

Since threading splits a task, it is implemented to achieve faster computations. In this example, an integer array that has ten elements is declared, and its sum is calculated. Instead of calculating the sum using one for-loop that iterates over the entire array and sums its values, two threads are created that each sum half the array and return the result to the main thread.

svg viewer

Demo

1 of 7

Code

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct data{
int* arr;
int thread_num;
} data;
int arrSize = 10;
void* halfSum(void* p){
data* ptr = (data*)p;
int n = ptr->thread_num;
// Declare sum dynamically to return to join:
int* thread_sum = (int*) calloc(1, sizeof(int));
if(n == 0){
for(int i = 0; i < arrSize/2; i++)
thread_sum[0] = thread_sum[0] + ptr->arr[i];
}
else{
for(int i = arrSize/2; i < arrSize; i++)
thread_sum[0] = thread_sum[0] + ptr->arr[i];
}
pthread_exit(thread_sum);
}
int main(void){
// Declare integer array [1,2,3,4,5,6,7,8,9,10]:
int* int_arr = (int*) calloc(arrSize, sizeof(int));
for(int i = 0; i < arrSize; i++)
int_arr[i] = i + 1;
// Declare arguments for both threads:
data thread_data[2];
thread_data[0].thread_num = 0;
thread_data[0].arr = int_arr;
thread_data[1].thread_num = 1;
thread_data[1].arr = int_arr;
// Declare thread IDs:
pthread_t tid[2];
// Start both threads:
pthread_create(&tid[0], NULL, halfSum, &thread_data[0]);
pthread_create(&tid[1], NULL, halfSum, &thread_data[1]);
// Declare space for sum:
int* sum0;
int* sum1;
// Retrieve sum of threads:
pthread_join(tid[0], (void**)&sum0);
pthread_join(tid[1], (void**)&sum1);
printf("Sum of whole array = %i\n", *sum0 + *sum1);
return 0;
}

Explanation

1. Struct declaration

Declare struct data; it has a pointer to the array (arr) and the thread number (thread_num).

typedef struct data{
    int* arr;
    int thread_num;
} data;

2. Thread routine

Declare the method halfSum() with return type void *, which will begin when the thread starts. The parameter type is also void * so that a struct can be passed. thread_num indicates which half of the array to sum. Since threads can only return references to dynamically allocated memory, space for thread_sum is created on the heap.

void* halfSum(void* p){
    data* ptr = (data*)p;
    int n = ptr->thread_num;
    
    // Declare sum dynamically to return to join:
    int* thread_sum = (int*) calloc(1, sizeof(int));
    
    if(n == 0){
        for(int i = 0; i < arrSize/2; i++)
            thread_sum[0] = thread_sum[0] + ptr->arr[i];
    }
    else{
        for(int i = arrSize/2; i < arrSize; i++)
            thread_sum[0] = thread_sum[0] + ptr->arr[i];
    }
    
    pthread_exit(thread_sum);
}

3. Initialize struct

Two objects of type data are created for each thread and initialized with the correct thread numbers (00 for the first thread and 11 for the second thread). arr, in both the objects, refers to the start of the array.

data thread_data[2];
thread_data[0].thread_num = 0;
thread_data[0].arr = int_arr;
    
thread_data[1].thread_num = 1;
thread_data[1].arr = int_arr;

4. Declare thread IDs

An array of type pthread_t is created to hold the ID of each thread.

pthread_t tid[2];

5. Create threads

Create both threads using the correct arguments with pthread_create().

pthread_create(&tid[0], NULL, halfSum, &thread_data[0]);

pthread_create(&tid[1], NULL, halfSum, &thread_data[1]);

6. Join threads

pthread_join() retrieves the result of both threads. sum0 points to the first thread’s sum, and sum1 points to the second thread’s sum.

int* sum0;
int* sum1;
    
pthread_join(tid[0], &sum0);
pthread_join(tid[1], &sum1);
Copyright ©2024 Educative, Inc. All rights reserved