我正在尝试使用C中的线程。我需要我的一个线程处理整个数组的一半,并合并它的一半。为此,我为整个数组和两半创建了一个全局数组指针。在运行时使用malloc
分配。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
void *process1(void *arg);
void *process2(void *arg);
void *process3(void *arg);
void *process4(void *arg);
void *process5(void *arg);
void merge(int *arr, int l, int m, int r);
void mergeSort(int *arr, int l, int r);
int *array;
int *arr_first;
int *arr_second;
int arr_s;
size_t n_size;
int n_size_i;
pthread_mutex_t mutex;
main(int argc, char *argv[]) {
arr_s = atoi(argv[1]);
n_size = arr_s / 2;
n_size_i = arr_s / 2;
array = malloc (arr_s * sizeof (int));
arr_first = malloc(arr_s / 2 * sizeof(int));
if (arr_s % 2 == 0)
arr_second = malloc((n_size) * sizeof (int));
else
arr_second = malloc((n_size+1) * sizeof(int));
pthread_t tid1, tid2, tid3, tid4, tid5;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid1, &attr, process1, NULL);
pthread_join(tid1, NULL);
printf("---------------------------------------------------------------------------THREAD 2 AND 3 ARE CURRENTLY SORTING THE NUMBERS-------------------------------------------------------------------------n");
pthread_create(&tid2, &attr, process2, NULL);
pthread_create(&tid3, &attr, process3, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
pthread_create(&tid4, &attr, process4, NULL);
pthread_join(tid4, NULL);
pthread_create(&tid5, &attr, process5, NULL);
pthread_join(tid5, NULL);
free(array);
free(arr_first);
free(arr_second);
exit(0);
}
以下是我的线程im在(线程2(上遇到问题时的函数外观。目前,它所做的一切都占用了整个数组的前半部分,然后逐个获取值并将其放入自己的值中。然后我打印出数组。然后最后对数组指针调用mergesort
。
void *process2(void *arg) {
int j = 0;
for (; j < (arr_s / 2); j++) {
arr_first[j] = array[j];
}
int j2;
for (j2 = 0; j2 < (arr_s / 2); j2++) {
printf("*%dt", arr_first[j2]);
if ((j2 + 1) % 25 == 0 && j2 > 0)
printf("n");
}
mergeSort(arr_first, 0, (arr_s / 2) - 1);
pthread_exit (0);
}
以下是我的合并和合并排序功能:
//Merges two subarrays of arr[]
//First subarry is arr[l..m]
//Second subarry is arr[m+1..r]
void merge(int *arr, int l, int m, int r) {
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
//create temp arrays
int L[n1], R[n2];
//copy data to temp array L[] and R[]
for (i = 0; i < n1; i++)
L[i] = arr[l+i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
//merge the temp arrays back in arr[l..r]
i = 0; j = 0; k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
//copy remaining elements of L[], if there are any
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
//same for R[]
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
void mergeSort(int *arr, int l, int r) {
if (l < r) {
int m = 1 + (r - 1) / 2;
//Sort first and second halves
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
出于某种原因,当我调用merge sort时,它将保持递归调用的次数远远超过数组中的元素。在mergeSort函数中,我将print语句放在其他语句之前,print语句执行50000多次,甚至更多。但是,如果我将print语句放在mergeSort中的merge调用之前,它就永远不会被执行。
mergeSort
中中点的计算不正确:l
和1
之间存在混淆。应该是:
int m = l + (r - l) / 2;
命名变量l
非常容易出错。使用left
或low
:
void mergeSort(int *arr, int left, int right) {
if (left < right) {
int m = left + (right - left) / 2;
//Sort first and second halves
mergeSort(arr, left, m);
mergeSort(arr, m + 1, right);
merge(arr, left, m, right);
}
}