我正在使用多线程程序对数组进行排序。首先,我将阵列分成两半。一个线程将前一半排序,另一个线程将后一半排序,最后一个线程将两个半部分合并在一起。我使用快速排序对每个部分进行排序。问题是,当我打印排序的数组时,它仅为0。
我一直在使用print语句来检查数组的内容。最初,快速排序似乎可行,但是现在我得到了正确的数组,但添加了额外的数字。我认为问题可能是内存被覆盖,但是我真的不确定,因此我包含的代码超出了必要。
*注意:mainarr是一个全局变量,声明为:int *mainarr
//function to merge two halves in result array
void merge(int l[], int r[], int size_left, int size_right)
{
//iterator variables, start at 0
int i = 0, j = 0, k = 0;
// Traverse both array
while (i < size_left && j < size_right)
{
if (l[i] < r[j]){
mainarr[k] = l[i];
i++;
k++;
}
else{
mainarr[k] = r[j];
k++;
j++;
}
}
// Store remaining elements of first array
while (i < size_left){
mainarr[k] = l[i];
k++;
i++;
}
// Store remaining elements of second array
while (j < size_right){
mainarr[k] = r[j];
k++;
j++;
}
}
//compare function for qsort
int compare(const void *a, const void *b){
return (*(int*)a - *(int*)b);
}
//thread begins control in this function
//this function is called from pthread_create
void *runner(void* param) {
int threadID = atoi(param);
int midpoint = size/2, index, r;
int *left = malloc(midpoint*sizeof(int));
int *right = malloc((size-midpoint)*sizeof(int));
//if first thread, sort "left" array
if(threadID == 1){
int i;
index=0;
//create "left" array
for(i=0; i < midpoint; i++){
left[index] = mainarr[i];
index++;
}
//sort array
qsort(left, midpoint, sizeof(int), compare);
printf("LEFT array: ");
for(r = 0; r < size; r++)
printf("%d ", left[r]);
}
//if second thread, sort "right" array
else if(threadID == 2){
int j;
index=0;
//create "right" array
for(j=midpoint; j < size; j++){
right[index] = mainarr[j];
index++;
}
//sort array
qsort(right, (size-midpoint), sizeof(int), compare);
printf("RIGHT array: ");
for(r = 0; r < size; r++)
printf("%d ", right[r]);
}
//if third thread, merge the left and right arrays
else if(threadID == 3){
merge(left, right, 4, 5);
}
//empty else to satisfy convention
else{}
pthread_exit(0);
}
我一直在使用的示例是数组[7,0,2,33,234,1,3,67,54]
。因此,我希望排序后的“ left”数组为[0,2,7,33]
,排序后的“ right”数组为[1,3,54,67,234]
,整个排序后的数组为[0,1,2,3,7,33,54,67,234]
。但是,实际排序的“左”数组是[0, 2, 7, 33, 0, 0, 37, 0, 0]
,实际排序的“右”数组是[1, 3, 54, 67, 234, 0, 132881, 0, 0]
,而实际整个排序的数组是[0, 0, 0, 0, 0, 0, 0, 0, 0]
我不确定问题是什么-是线程,内存覆盖自身还是其他原因。有什么帮助,谢谢。
更新/解决方案:我在if语句之外分配左右空间,因此,当新线程启动时,它将清除左右数组的内容,导致全0。
答案 0 :(得分:2)
但是,实际排序的“左”数组是[0,2,7,33,0,0,37,0, 0],
不,不是。
实际排序的“正确”数组是[1、3、54、67、234、0、132881, 0,0]
不,不是。
您正在打印超出这些数组分配范围的元素。结果行为是不确定的。您很(不幸)该程序不会崩溃。请注意,这些数组的实际范围内的值符合您的预期。
实际的整个排序数组是[0,0,0,0,0,0,0,0,0]
排序。
我可以相信那是打印出来的内容,因为您要合并第三个线程分配的两个数组,并且它们的内容永远都不会设置。这里的行为仍然是未定义的,并且当每个线程分配自己的单独子数组对(并泄漏它们)时,完全没有理由期望第三个线程将看到来自其他两个线程的排序结果。 / p>
我实际上看不到单独的合并线程的意义。在两个quicksort线程完成之前,无法执行合并,并且由于它不能与其他线程同时运行,因此我认为没有理由不将该工作留给主线程。总体而言,我建议这样做: