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

调用pthread_join()后pthread_create()失效,线程tid为0致输出缺失

多线程程序输出缺失问题解决

问题概述

编写的多线程程序预期打印0到99的数字,但实际输出存在缺失。排查发现首次执行pthread_join()循环后,后续info[k].tid变为0,导致pthread_create()无法正常工作。

原代码

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

typedef struct {
    pthread_t tid;
    int i;
    int res;
} thread_info;

void *square(void *data) {
    thread_info *info = (thread_info*) data;
    info->res = info->i;
    return NULL;
}

int main(void) {
    int nthread = 2;
    int lim = 100;
    int *results;

    results = calloc(lim, sizeof(int));
    thread_info *info = calloc(nthread, sizeof(thread_info));

    for (int i=0; i<lim; i++) {
        info[i % nthread].i = i;
        pthread_create(&info[i].tid, NULL, square, info + (i%nthread));

        if (((i+1) % nthread)) {
            continue;
        }

        for (int k=0; k<nthread; k++) {
            pthread_join(info[k].tid, NULL);
        }

        for (int k=0; k<nthread; k++) {
            results[info[k].i] = info[k].res;
        }

        memset(info, 0, sizeof(thread_info) * nthread);
    }

    for (int i=0; i<100; i++) {
        printf("%d\n", results[i]);
    }

    return 0;
}

问题根源

  1. 数组越界访问:pthread_create的第一个参数错误传入&info[i].tid,但info数组仅分配了nthread(2)个元素。当i >= nthread时,info[i]属于越界访问,会破坏内存中的其他数据,导致tid被意外置0,引发未定义行为。
  2. 不必要的内存清零:memset(info, 0, ...)会将所有线程信息结构体清零,包括tid字段,这一操作多余且会干扰后续线程创建的正确性。

修复方案

  1. 修正pthread_create的第一个参数,改为&info[i%nthread].tid,确保始终访问info数组的有效索引。
  2. 移除不必要的memset操作,下一轮循环会覆盖结构体中的i字段,tid也会被新的线程创建操作覆盖。
  3. 补充内存释放代码,避免内存泄漏。

修复后代码

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

typedef struct {
    pthread_t tid;
    int i;
    int res;
} thread_info;

void *square(void *data) {
    thread_info *info = (thread_info*) data;
    info->res = info->i;
    return NULL;
}

int main(void) {
    int nthread = 2;
    int lim = 100;
    int *results;

    results = calloc(lim, sizeof(int));
    thread_info *info = calloc(nthread, sizeof(thread_info));

    for (int i=0; i<lim; i++) {
        int idx = i % nthread;
        info[idx].i = i;
        // 使用正确的索引获取tid地址,避免越界
        pthread_create(&info[idx].tid, NULL, square, &info[idx]);

        if (((i+1) % nthread)) {
            continue;
        }

        for (int k=0; k<nthread; k++) {
            pthread_join(info[k].tid, NULL);
        }

        for (int k=0; k<nthread; k++) {
            results[info[k].i] = info[k].res;
        }
    }

    for (int i=0; i<100; i++) {
        printf("%d\n", results[i]);
    }

    // 释放分配的内存
    free(results);
    free(info);

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:10:21