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
相关产品推荐
相关产品推荐

