You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

修正方案

由于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:23:21