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

C语言多线程代码问题:打印顺序异常且程序挂起

多线程C程序的输出顺序与挂起问题修复

问题分析

1. 输出顺序混乱+线程号错误

  • 输出顺序不符:主线程打印a的操作和线程打印信息的操作没有同步约束,线程被创建后可能立即被调度执行,抢在主线程的printf之前输出内容。
  • 线程号重复/错误:传递给线程的是循环变量i的地址,主线程循环会持续修改i的值,线程读取*(int*)data时,拿到的往往是i更新后的最新值,而非创建线程时的i。

2. 程序挂起无法终止

主线程循环中,i初始为0,先执行i++变为1,再调用pthread_create(&array[i], ...),也就是往array[1]到array[10]写入线程ID。但数组array大小为N=10,下标范围是0-9,array[10]属于数组越界,会触发非法内存访问。后续pthread_join遍历i=0到9时,array[0]从未被初始化,调用pthread_join未初始化的线程ID会触发未定义行为,导致程序挂起。


修复后的代码

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

#define N 10

static int a = 0;
pthread_mutex_t mut_a;
pthread_mutex_t mut_print;

// 用于传递线程独立数据的结构体
typedef struct {
    int thread_num;
} ThreadData;

void *dummy(void *data) {
    ThreadData *td = (ThreadData*)data;

    // 互斥保护变量a的递增操作
    pthread_mutex_lock(&mut_a);
    a++;
    pthread_mutex_unlock(&mut_a);

    // 互斥同步输出,保证主线程先打印a的值
    pthread_mutex_lock(&mut_print);
    printf("In the dummy function.. thread %d \n", td->thread_num);
    pthread_mutex_unlock(&mut_print);

    free(td);
    return NULL; // 线程函数必须返回void*类型
}

int main() {
    int ret;
    pthread_t array[N];

    pthread_mutex_init(&mut_a, NULL);
    pthread_mutex_init(&mut_print, NULL);

    for (int i = 0; i < N; i++) {
        // 为每个线程分配独立的数据结构,避免共享循环变量
        ThreadData *td = malloc(sizeof(ThreadData));
        if (!td) {
            perror("malloc failed");
            return 1;
        }
        td->thread_num = i + 1; // 线程号从1到10

        // 正确使用数组下标,避免越界
        ret = pthread_create(&array[i], NULL, dummy, td);
        if (ret != 0) {
            printf("Error creating thread %d, code %d.. \n", i+1, ret);
            free(td);
            // 清理已创建的线程
            for (int j = 0; j < i; j++) {
                pthread_join(array[j], NULL);
            }
            pthread_mutex_destroy(&mut_a);
            pthread_mutex_destroy(&mut_print);
            return 1;
        }

        // 互斥同步输出,确保先打印a的值
        pthread_mutex_lock(&mut_print);
        printf("a value is: %d\n", a);
        pthread_mutex_unlock(&mut_print);
    }

    // 等待所有线程执行完毕
    for (int i = 0; i < N; i++) {
        pthread_join(array[i], NULL);
    }

    pthread_mutex_destroy(&mut_a);
    pthread_mutex_destroy(&mut_print);

    return 0;
}

关键修改点

  1. 解决数组越界:调整循环逻辑,直接使用i从0到9作为数组下标,确保array[i]都被正确赋值。
  2. 避免共享变量问题:用动态分配的ThreadData结构体为每个线程传递独立的线程号,不再传递循环变量的地址。
  3. 同步输出顺序:新增mut_print互斥锁,约束主线程和线程的输出操作,保证先打印a的值,再打印线程信息。
  4. 完善资源清理:线程函数中释放动态分配的内存,创建线程失败时清理已创建的线程和互斥锁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:05:19