C语言多线程统计程序异常:均值/最值计算结果错误排查
C语言多线程统计程序错误排查
问题描述
编写C语言多线程程序,通过三个工作线程分别计算命令行传入数字列表的均值、最大值、最小值。执行命令:
./multithreadexe 90 81 78 95 79 72 85
预期输出82 72 95,但实际输出0 90 90,无编译错误,怀疑线程未正确更新结果变量或数组传递存在问题。
原程序代码
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #define NUM_THREADS 3 // Variables that hold the final results, integer data type for simplicity. Do not change these variables. int avgNum; int minNum; int maxNum; // Function prototypes. Definition is at the bottom. Do not change the declaration of these functions. void *avgfunc(void *param); void *minfunc(void *param); void *maxfunc(void *param); int main(int argc, char* argv[]) { // Declare an array of integers to hold the numbers passed as command-line arguments. int numArray[argc - 1]; int i; // Convert the string arguments to integers and store them in the array. for (i = 1; i < argc; i++) { numArray[i - 1] = atoi(argv[i]); } // Create thread IDs pthread_t threads[NUM_THREADS]; // Create thread attributes pthread_attr_t attr; // Initialize thread attributes pthread_attr_init(&attr); // Create threads pthread_create(&threads[0], &attr, avgfunc, numArray); pthread_create(&threads[1], &attr, minfunc, numArray); pthread_create(&threads[2], &attr, maxfunc, numArray); // Wait for threads to exit for (i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } // Printing the results. printf("%d %d %d\n", avgNum, minNum, maxNum); return 0; } void *avgfunc(void *param) { int argc = 0; int *numArray = (int *)param; int sum = 0; int i; for (i = 0; i < argc - 1; i++) { sum += numArray[i]; } avgNum = sum / (argc - 1); pthread_exit(0); return 0; } void *minfunc(void *param) { int argc = 0; int *numArray = (int *)param; int min = numArray[0]; int i; for (i = 1; i < argc - 1; i++) { if (numArray[i] < min) { min = numArray[i]; } } minNum = min; pthread_exit(0); return 0; } void *maxfunc(void *param) { int argc = 0; int *numArray = (int *)param; int max = numArray[0]; int i; for (i = 1; i < argc - 1; i++) { if (numArray[i] > max) { max = numArray[i]; } } maxNum = max; pthread_exit(0); return 0; }
错误原因分析
- 核心问题:线程函数未获取有效数组长度
每个线程函数内部都定义了int argc = 0;,导致循环条件i < argc -1等价于i < -1,循环完全不会执行:- 均值计算:sum初始为0,除以
argc-1=-1,结果为0,因此avgNum输出0; - 最小值/最大值计算:循环未执行,直接将数组第一个元素(90)赋值给
minNum和maxNum,因此输出90 90。
- 均值计算:sum初始为0,除以
修正方案
由于pthread线程函数仅能接收一个void*参数,需要将数组指针和元素长度打包为结构体传递:
1. 定义线程参数结构体
typedef struct { int *arr; int len; } ThreadData;
2. 主线程中填充结构体并传递给线程
修改main函数中创建线程的部分:
// 打包数组和长度 ThreadData data; data.arr = numArray; data.len = argc - 1; // 创建线程时传递结构体地址 pthread_create(&threads[0], &attr, avgfunc, &data); pthread_create(&threads[1], &attr, minfunc, &data); pthread_create(&threads[2], &attr, maxfunc, &data);
3. 修改线程函数解析参数
以avgfunc为例,其余两个线程函数同理修改:
void *avgfunc(void *param) { ThreadData *data = (ThreadData*)param; int sum = 0; int i; for (i = 0; i < data->len; i++) { sum += data->arr[i]; } avgNum = sum / data->len; pthread_exit(NULL); return NULL; }
修正后完整代码
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #define NUM_THREADS 3 // Variables that hold the final results, integer data type for simplicity. Do not change these variables. int avgNum; int minNum; int maxNum; // 定义线程参数结构体 typedef struct { int *arr; int len; } ThreadData; // Function prototypes. Definition is at the bottom. Do not change the declaration of these functions. void *avgfunc(void *param); void *minfunc(void *param); void *maxfunc(void *param); int main(int argc, char* argv[]) { // Declare an array of integers to hold the numbers passed as command-line arguments. int numArray[argc - 1]; int i; // Convert the string arguments to integers and store them in the array. for (i = 1; i < argc; i++) { numArray[i - 1] = atoi(argv[i]); } // Create thread IDs pthread_t threads[NUM_THREADS]; // Create thread attributes pthread_attr_t attr; // Initialize thread attributes pthread_attr_init(&attr); // 打包数组和长度 ThreadData data; data.arr = numArray; data.len = argc - 1; // Create threads pthread_create(&threads[0], &attr, avgfunc, &data); pthread_create(&threads[1], &attr, minfunc, &data); pthread_create(&threads[2], &attr, maxfunc, &data); // Wait for threads to exit for (i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } // Printing the results. printf("%d %d %d\n", avgNum, minNum, maxNum); return 0; } void *avgfunc(void *param) { ThreadData *data = (ThreadData*)param; int sum = 0; int i; for (i = 0; i < data->len; i++) { sum += data->arr[i]; } avgNum = sum / data->len; pthread_exit(NULL); return NULL; } void *minfunc(void *param) { ThreadData *data = (ThreadData*)param; int min = data->arr[0]; int i; for (i = 1; i < data->len; i++) { if (data->arr[i] < min) { min = data->arr[i]; } } minNum = min; pthread_exit(NULL); return NULL; } void *maxfunc(void *param) { ThreadData *data = (ThreadData*)param; int max = data->arr[0]; int i; for (i = 1; i < data->len; i++) { if (data->arr[i] > max) { max = data->arr[i]; } } maxNum = max; pthread_exit(NULL); return NULL; }
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

