-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNumberSorter_Multithreaded.c
201 lines (165 loc) · 5.54 KB
/
NumberSorter_Multithreaded.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
//Function Prototypes
void* sorter(void* params);
void* merger(void* params);
//Index Struct
typedef struct {
int from_index;
int to_index;
} parameters;
//Global Arrays
int* origArray;
int* sortedArray;
int threadCount = 1;
int main(int argc, char* argv[]) {
int n;
bool isOdd = false;
//Parameter object for sorter and merger threads.
parameters T1params;
parameters T2params;
//POSIX struct variables for the three threads.
pthread_t sortThread1;
pthread_t sortThread2;
pthread_t mergeThread;
//Using dynamic arrays to get a dynamic size of the array from the user.
printf("Enter the number of integers in the list: ");
scanf("%d", &n);
//Allocating memory for the arrays.
origArray = malloc(n * sizeof(int));
sortedArray = malloc(n * sizeof(int));
//Error handling.
if (origArray == NULL || sortedArray == NULL) {
perror("Unable to allocate memory.\n");
exit(1);
}
for (int i = 0; i < n; i++) {
printf("Enter the integer #%d: ", i + 1);
scanf("%d", &origArray[i]);
}
printf("\n");
//If the size is odd, set the flag to true.
//This will be used to accomodate the odd number of integers.
//Setting up the parameters for Sorter Thread #1 as per the conditions.
if ((n % 2) != 0) {
isOdd = true;
T1params.from_index = 0;
T1params.to_index = (n/2) + 1;
}
else {
isOdd = false;
T1params.from_index = 0;
T1params.to_index = n/2;
}
//Setting parameters for Sorter Thread #2 as per the conditions.
T2params.from_index = T1params.to_index;
T2params.to_index = n;
//Printing the raw, unsorted array as received from input.
printf("Unsorted List of Integers:\n");
for (int i = 0; i < n; i++) {
printf("%d ", origArray[i]);
}
printf("\n");
//Creating Sorter Thread #1, and passing the parameters.
if ((pthread_create(&sortThread1, NULL, sorter, &T1params)) != 0) {
perror("Error creating thread 1");
exit(1);
}
//Creating Sorter Thread #2, and passing the parameters.
if ((pthread_create(&sortThread2, NULL, sorter, &T2params)) != 0) {
perror("Error creating thread 2");
exit(1);
}
//Waiting for the Sorter Threads to finish.
pthread_join(sortThread2, NULL);
//Creating the Merger Thread, and passing the parameters.
if ((pthread_create(&mergeThread, NULL, merger, &T2params)) != 0) {
perror("Error creating merger thread");
exit(1);
}
//Waiting for merger thread to finish.
pthread_join(mergeThread, NULL);
//Printing the final sorted array.
printf("----------------------------------------\n");
printf("Final Sorted List of Integers:\n");
for (int i = 0; i < n; i++) {
printf("%d ", sortedArray[i]);
}
printf("\n");
//Freeing the allocating space to ensure no resource leaks.
free(origArray);
free(sortedArray);
return 0;
}
//Sorter Function:
void* sorter(void* params) {
printf("----------------------------------------\n");
printf("SORTING THREAD %d:\n", threadCount);
//Getting the parameters from the struct.
int from_index = ((parameters*)params)->from_index;
int to_index = ((parameters*)params)->to_index;
printf("Making sublist from index #%d to index #%d and sorting...\n", from_index, to_index);
//Printing the unsorted sublist as per the parameters.
printf("Unsorted Sublist:\n");
for (int i = from_index; i < to_index; i++) {
printf("%d ", origArray[i]);
}
//Sorting the sublist using bubble sort.
for (int i = from_index; i < to_index; i++) {
for (int j = i + 1; j < to_index; j++) {
if (origArray[i] > origArray[j]) {
int temp = origArray[i];
origArray[i] = origArray[j];
origArray[j] = temp;
}
}
}
//Printing the sorted sublist as per the parameters.
printf("\nSorted Sublist:\n");
for (int i = from_index; i < to_index; i++) {
printf("%d ", origArray[i]);
}
printf("\nThread %d done, exiting..\n", threadCount);
//Incrementing thread count.
threadCount++;
//Returning NULL for successful execution.
return NULL;
}
//Merger Function:
void* merger(void* params) {
printf("----------------------------------------\n");
printf("MERGER THREAD %d:\n", threadCount);
//Getting the parameters from the struct.
int from_index = ((parameters*)params)->from_index;
int to_index = ((parameters*)params)->to_index;
//Printing Sublist 1 from Thread 1.
printf("Sublist 1: ");
for (int i = 0; i < from_index; i++) {
printf("%d ", origArray[i]);
}
//Printing Sublist 2 from Thread 2.
printf("\nSublist 2: ");
for (int i = from_index; i < to_index; i++) {
printf("%d ", origArray[i]);
}
printf("\nMerging sublists...\n");
//Copying the two sublists to the sorted array.
for (int i = 0; i < to_index; i++) {
sortedArray[i] = origArray[i];
}
//Sorting the final array.
for (int i = 0; i < to_index; i++) {
for (int j = i + 1; j < to_index; j++) {
if (sortedArray[i] > sortedArray[j]) {
int temp = sortedArray[i];
sortedArray[i] = sortedArray[j];
sortedArray[j] = temp;
}
}
}
printf("Merging done. Merger Thread exiting...\n");
return NULL;
}