提问人:Debak Roy 提问时间:10/31/2023 最后编辑:halferDebak Roy 更新时间:11/8/2023 访问量:118
如何使用线程调试此 C 代码,以及如何修复该问题
How to debug this C code using threads, and how to fix the issue
问:
代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void display(int *arr, int size) {
int i;
for(i=0; i<size; i++)
printf("%d ", arr[i]);
printf("\n");
}
void display2(int *arr, int size) {
int i;
for(i=1; i<size; i++)
printf("%d ", arr[i]);
printf("\n");
}
void mergeA(int* arr, int lb, int ub, int mid) {
// printf("Inside mergeA\n");
int i=lb, j=mid+1, k=lb;
int newarr[1000];
while(i<=mid && j<=ub) {
if(arr[i] > arr[j])
newarr[k++] = arr[j++];
else
newarr[k++] = arr[i++];
}
for(; i<=mid; i++)
newarr[k++] = arr[i];
for(; j<=ub; j++)
newarr[k++] = arr[j];
for(i=lb; i<=ub; i++)
arr[i] = newarr[i];
}
void mergeD(int* arr, int lb, int ub, int mid) {
// printf("Inside mergeD\n");
int i=lb, j=mid+1, k=lb;
int newarr[1000];
while(i<=mid && j<=ub) {
if(arr[i] < arr[j])
newarr[k++] = arr[j++];
else
newarr[k++] = arr[i++];
}
for(; i<=mid; i++)
newarr[k++] = arr[i];
for(; j<=ub; j++)
newarr[k++] = arr[j];
for(i=lb; i<=ub; i++)
arr[i] = newarr[i];
}
void mergeSortA(int* arr, int lb, int ub) {
// printf("Inside mergeSortA\n");
if(lb<ub) {
int mid = (lb+ub)/2;
mergeSortA(arr, lb, mid);
mergeSortA(arr, mid+1, ub);
mergeA(arr, lb, ub, mid);
}
}
void mergeSortD(int* arr, int lb, int ub) {
// printf("Inside mergeSortD\n");
if(lb<ub) {
int mid = (lb+ub)/2;
mergeSortD(arr, lb, mid);
mergeSortD(arr, mid+1, ub);
mergeD(arr, lb, ub, mid);
}
}
void* sort_a(void* args) {
int* arr = (int*)malloc(sizeof(int)*1000);
arr = (int*)args;
int size = arr[0];
printf("Inside Sort A: ");
display2(arr, size);
mergeSortA(arr, 1, size-1);
printf("After Sort A: ");
display2(arr, size);
pthread_exit((void*)arr);
}
void* sort_d(void* args) {
int* arr = (int*)malloc(sizeof(int)*1000);
arr = (int*)args;
int size = arr[0];
printf("Inside Sort D: ");
display2(arr, size);
mergeSortD(arr, 1, size-1);
printf("After Sort D: ");
display2(arr, size);
pthread_exit((void*)arr);
}
int main() {
pthread_t t1, t2;
int arr[1000];
int i=0, j, k1=1, k2=1;
//Taking the array as input
while(1) {
printf("Enter an element or 'quit' to stop input: ");
char input[100];
scanf("%s", input);
if(strcmp(input, "quit") == 0)
break;
arr[i++] = atoi(input);
}
printf("The Array:\n");
display(arr, i);
//Spliting the array into two
int arr1[1000], arr2[1000];
for(j=0; j<i; j++) {
if(j<i/2)
arr1[k1++]=arr[j];
else
arr2[k2++]=arr[j];
}
//Storing size in index 0
arr1[0] = k1;
arr2[0] = k2;
//Creating the threads
pthread_create(&t1, NULL, &sort_a, (void*)arr1);
pthread_create(&t2, NULL, &sort_d, (void*)arr2);
//Joining the threads
pthread_join(t1, (void*)arr1);
pthread_join(t2, (void*)arr2);
//After Sorting
printf("Main Thread:\n");
display2(arr1, k1);
display2(arr2, k2);
}
我希望输出与函数(sort_a 和 sort_d)中的输出相同,但第一个索引中的元素始终是垃圾值。 注意:在这种情况下,第一个索引是 1,因为我将长度存储在第 0 个索引中
如您所见,主线程中的输出不正确。
答:
在 MergeD 中,比较应该是:
if(arr[i] > arr[j]) /* not if(arr[i] < arr[j]) */
sort_a 和 sort_d malloc 数组,但切勿释放它们。它们应释放分配的内存。两个合并函数都应使用 malloc 而不是使用大小为 1000 的局部数组,以便可以对更大的数组进行排序。
两个线程完成后,需要进行最终合并。
不需要为这两个线程设置一组单独的函数。
作为使用索引 0 表示数组大小的替代方法,pthread_create可以将指向结构的指针作为参数传递,其中结构将包含指向数组中元素的指针和大小。
不应将合并子数组作为参数传递给作为线程运行的排序函数。根据下面粘贴的 POSIX 线程规范函数原型,终止调用线程,并使该值可用于与终止线程的任何成功连接。该函数暂停调用线程的执行,直到目标线程终止。使用非 NULL 参数参数成功调用返回时,终止线程传递到的值应在 引用的位置中可用。arr
pthread_exit()
pthread_exit()
value_ptr
pthread_join()
pthread_join()
value_ptr
pthread_exit()
value_ptr
void pthread_exit(void *value_ptr);
int pthread_join(pthread_t thread, void **value_ptr);
您应该通过以下方式从中获取值:main()
pthread_exit()
int main() {
...
...
int *result1=0;
int *result2=0;
...
...
pthread_join(t2, (void **) &result2);
pthread_join(t1, (void **) &result1);
...
printf ("\nstatus returned thread t1=%d", *result1);
printf ("\nstatus returned thread t2=%d", *result2);
...
}
在排序函数中,设置如下。不要为 call 参数引用本地 /stack 变量。value_ptr
pthread_exit()
value_ptr
void * sort_d(void * args) {
...
int *retval;
retval = (int *) (malloc (sizeof (int));
...
*retval = 0; // any value you want to return
pthread_exit(retval);
}
或者,您可以在排序函数中发出返回值,而不是调用 .如下图所示,由于 sort 函数的返回值也用作线程的退出值:value_ptr
pthread_exit()
retval
void * sort_d(void * args) {
...
int *retval;
retval = (int *) (malloc (sizeof (int));
...
*retval = 0 // set to any value you want to return
return retval;
}
pthread 函数 ,如果成功,则返回零。您可能需要检查这些函数的返回值是否存在任何错误。pthread_create()
pthread_join()
评论
pthread_join(t1, (void*)arr1)
将用结果覆盖数组中的前两个(假设是 64 位架构)int。您没有检查结果,因此请考虑将其存储在其他地方。int* arr = (int*)malloc(sizeof(int)*1000); arr = (int*)args;
我们又来了。int pthread_join(pthread_t thread, void **retval);
你明白为什么第二个参数的类型是而不是吗?void**
void*