I wrote a program that implements the mergeSort algorithm, which sorts across multiple threads. The algorithm is able to spread the sorted vector over several threads The program contains mutexes to protect global counters that are incremented by each thread.
I would like you to help me modify the program so that I do not use so many global variables. I also think that the program is making too many copies and that problems may occur
#include <stdio.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
pthread_mutex_t mutex_p = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_pi = PTHREAD_MUTEX_INITIALIZER;
int MAX; // number of elements in the array
int THREAD_MAX; // number of threads
int idx[20]; // hold the right end at each vector subdivision
int p_i = 0;
int *a;
int part = 0;
// mergeSort function to interclass two parts
void merge(int l1, int h1, int h2)
{
int count = h2 - l1 + 1;
int sorted[count];
int i = l1, k = h1 + 1, m = 0;
while (i <= h1 && k <= h2)
{
if (a[i] < a[k])
sorted[m++] = a[i++];
else if (a[k] < a[i])
sorted[m++] = a[k++];
else if (a[i] == a[k])
{
sorted[m++] = a[i++];
sorted[m++] = a[k++];
}
}
while (i <= h1)
sorted[m++] = a[i++];
while (k <= h2)
sorted[m++] = a[k++];
for (i = 0; i < count; i++, l1++)
a[l1] = sorted[i];
}
// mergeSort function
void merge_sort(int low, int high)
{
// calculates the middle of the array
int mid = low + (high - low) / 2;
if (low < high)
{
// I call the first half
merge_sort(low, mid);
// I call the second half
merge_sort(mid + 1, high);
// interclassification between the two halves
merge(low, mid, high);
}
}
// thread function for multi-threading
void *mergeSort(void *arg)
{
pthread_mutex_lock(&mutex_p);
int thread_part = part++;
pthread_mutex_unlock(&mutex_p);
// calculate the minimum and maximum
int low = thread_part * (MAX / THREAD_MAX);
int high = (thread_part + 1) * (MAX / THREAD_MAX) - 1;
// allocate the rest of the original array to the last thread
if (thread_part == THREAD_MAX - 1)
{
high = MAX - 1;
}
// stores the right edge for each split array
pthread_mutex_lock(&mutex_pi);
idx[++p_i] = high;
pthread_mutex_unlock(&mutex_pi);
// calculate the midpoint
int mid = low + (high - low) / 2;
merge_sort(low, mid);
merge_sort(mid + 1, high);
merge(low, mid, high);
return NULL;
}
void isSorted(int len)
{
if (len == 1)
{
printf("Sorting completed\n");
return;
}
int i;
for (i = 1; i < len; i++)
{
if (a[i] < a[i - 1])
{
printf("Sorting is not complete\n");
return;
}
}
printf("Sorting completed\n");
return;
}
// The main program
int main()
{
printf("Enter the number of items in the array:");
scanf("%d", &MAX);
printf("Enter the number of threads you want:");
scanf("%d", &THREAD_MAX);
// generates random number in array up to 1000
a = malloc(MAX * sizeof(int));
srand(time(NULL));
for (int i = 0; i < MAX; i++)
{
a[i] = rand() % 1000;
}
// t1 and t2 to calculate the time to mergeSort
clock_t t1 = clock();
pthread_t threads[THREAD_MAX];
// thread creation
for (int i = 0; i < THREAD_MAX; i++)
{
pthread_create(&threads[i], NULL, mergeSort, (void *)NULL);
}
// joining all threads
for (int i = 0; i < THREAD_MAX; i++)
{
pthread_join(threads[i], NULL);
}
// merging on the last elements
int p = 1;
int mid, high;
for (int q = 1; q < THREAD_MAX; q++)
{
mid = idx[p];
p++;
high = idx[p];
merge(0, mid, high);
}
clock_t t2 = clock();
printf("Time required: %f\n", (double)(t2 - t1) / CLOCKS_PER_SEC);
isSorted(MAX);
//sorted array display
printf("Sorted array: ");
for (int i = 0; i < MAX; i++)
printf("%d ", a[i]);
printf("\n");
free(a);
return 0;
}