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

多线程蒙特卡洛法计算PI的C语言代码非void返回报错问题求解

问题修复方案

编译报错的根因

你遇到的non-void function doesn't return a value报错,是因为runner作为pthread线程入口函数,声明的返回类型是void*,但函数末尾没有返回任何值,不符合C语言的语法要求。

额外问题说明

你的原有代码还存在两处逻辑错误:

  • 计算PI的分母使用了初始值为0的局部变量points_per_thread,会触发除0错误,得到无效的无穷大结果
  • 没有实现你要求的「每结束一个线程就更新一次PI值」的逻辑,原有代码是所有线程执行完毕后才计算一次PI值

完整修正代码

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

long ppt; /* 每个线程生成的点数量 */

void *runner() {
    long incircle_thread = 0;
    unsigned int rand_state = rand();
    for (long i = 0; i < ppt; i++) {
        double x = rand_r(&rand_state) / ((double)RAND_MAX + 1) * 2.0 - 1.0;
        double y = rand_r(&rand_state) / ((double)RAND_MAX + 1) * 2.0 - 1.0;
        if (x * x + y * y < 1) {
            incircle_thread++;
        }
    }
    // 返回当前线程统计的圆内点数,无需全局锁
    return (void*)incircle_thread;
}

int main(int argc, const char *argv[])
{
    if (argc != 3) {
        fprintf(stderr, "usage: ./pi <总生成点数> <线程数>\n");
        exit(1);
    }
    long totalpoints = atol(argv[1]);
    int thread_count = atoi(argv[2]);
    ppt = totalpoints / thread_count;

    time_t start = time(NULL);
    srand((unsigned)time(NULL));
    pthread_t *threads = malloc(thread_count * sizeof(pthread_t));
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    for (int i = 0; i < thread_count; i++) {
        pthread_create(&threads[i], &attr, runner, NULL);
    }

    long total_incircle = 0;
    for (int i = 0; i < thread_count; i++) {
        void *ret;
        pthread_join(threads[i], &ret);
        // 累加当前线程返回的圆内点数
        total_incircle += (long)ret;
        // 每结束一个线程就更新计算PI值
        double current_pi = 4.0 * total_incircle / (double)(ppt * (i + 1));
        printf("第%d个线程执行完毕,当前PI计算值:%f\n", i+1, current_pi);
    }

    free(threads);
    printf("\n最终PI计算值:%f\n", 4.0 * (double)total_incircle / (double)totalpoints);
    printf("总耗时:%d 秒\n", (unsigned int)(time(NULL) - start));
    return 0;
}

使用说明

如果要实现你要求的「5个线程每个生成1000个点」的效果,编译后执行以下命令即可:

./pi 5000 5

内容的提问来源于stack exchange,提问作者Bam19

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:15:05