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

Pthreads多线程程序输出异常咨询:为何打印次数不符预期?

问题分析与解决

你的代码出现输出不符合预期的情况,主要是两个关键问题导致的:

1. 主线程未等待子线程执行完成

你在main函数创建完5个线程后直接return 0;,这会立刻触发整个进程终止。进程终止时,操作系统会强制终止所有还在运行的子线程,但因为线程调度的不确定性,有时候部分线程可能刚好在主线程退出前开始执行,甚至因为参数问题读取到错误值,导致输出行数和内容不符合预期。

要解决这个问题,你需要在创建完所有线程后,使用pthread_join函数逐个等待每个子线程执行完毕,确保所有线程都完成任务后,主线程再退出。

2. 线程参数传递存在未定义行为

你在调用pthread_create时,把i + 1通过reinterpret_cast<void*>(i + 1)转换成指针传递给线程函数,然后在线程里再转成int。这种做法是未定义行为:你实际上是把一个整数数值当作内存地址来传递,而这个地址大概率是无效的内存区域。虽然在某些平台上可能看起来能运行,但线程调度的延迟会导致多个线程读取到相同的数值(比如你输出里重复的<4>或<5>),因为循环变量i在主线程里快速迭代,线程函数读取时可能i已经被更新了。

正确的做法是为每个线程分配独立的参数存储空间,比如动态分配int变量,或者用数组提前存储所有参数值,确保每个线程拿到的是独立且不会被覆盖的参数。

修正后的代码示例

#include<iostream>
#include<pthread.h>
using namespace std;

pthread_mutex_t mutex;

void* PrintHello(void *t) {
    int thread_num = *reinterpret_cast<int*>(t);
    pthread_mutex_lock(&mutex);
    cout << "Hello, World thread <" << thread_num << ">!" << endl;
    pthread_mutex_unlock(&mutex);
    // 释放为参数分配的内存
    delete static_cast<int*>(t);
    pthread_exit(NULL);
}

int main() {
    pthread_t threadId[5];
    pthread_mutex_init(&mutex, NULL);

    for(int i = 0; i < 5; i ++) {
        // 为每个线程分配独立的参数,避免被覆盖
        int* param = new int(i + 1);
        int rc = pthread_create(&threadId[i], NULL, PrintHello, param);
        if (rc != 0) {
            cerr << "Failed to create thread " << i + 1 << endl;
            delete param; // 创建失败时记得释放内存
            return 1;
        }
    }

    // 等待所有子线程执行完成
    for(int i = 0; i < 5; i++) {
        pthread_join(threadId[i], NULL);
    }

    pthread_mutex_destroy(&mutex); // 销毁互斥锁,释放资源
    return 0;
}

修正要点说明

  • 为每个线程动态分配独立的int参数,确保每个线程拿到的是唯一且不会被主线程循环变量覆盖的值。
  • 线程函数执行完毕后释放分配的内存,避免内存泄漏。
  • 使用pthread_join等待所有子线程完成,保证所有线程都能正常输出后,主线程再退出。
  • 添加了线程创建的错误检查,以及互斥锁的销毁操作,养成良好的资源管理习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:42:01