使用pthread按序打印数字出现死锁,寻求简易修复方案
问题分析与修复方案
核心问题
- 线程参数被覆盖:主线程中所有线程共享同一个
SFE实例,循环修改threadNumber.thread时,线程可能还未执行到读取该值的逻辑,导致多个线程拿到错误的线程编号,条件判断threadNum->turn != threadNum->thread永远不成立,触发死锁。 - 违反局部变量要求:代码中使用了
static全局的互斥锁、条件变量和线程数,不符合题目“仅使用局部变量”的限制。
修复后的代码
#include <pthread.h> #include <iostream> #include <stdlib.h> // 共享状态结构体:所有线程共享turn、mutex和cond struct SharedState { int turn; pthread_mutex_t bsem; pthread_cond_t waitTurn; }; // 每个线程的参数:包含共享状态指针和自身编号 struct ThreadArgs { SharedState* shared; int thread_id; }; void *thread_function(void *void_ptr_argv) { ThreadArgs *args = (ThreadArgs *) void_ptr_argv; SharedState* shared = args->shared; pthread_mutex_lock(&shared->bsem); // 等待轮到自己 while(shared->turn != args->thread_id){ pthread_cond_wait(&shared->waitTurn, &shared->bsem); } pthread_mutex_unlock(&shared->bsem); std::cout << "I am Thread " << args->thread_id << std::endl; pthread_mutex_lock(&shared->bsem); shared->turn++; pthread_cond_broadcast(&shared->waitTurn); pthread_mutex_unlock(&shared->bsem); // 释放线程参数内存 delete args; return nullptr; } int main() { int nthreads; std::cin >> nthreads; // 初始化共享状态(局部变量) SharedState shared; shared.turn = 0; pthread_mutex_init(&shared.bsem, NULL); pthread_cond_init(&shared.waitTurn, NULL); pthread_t *tid = new pthread_t[nthreads]; for(int i=0; i<nthreads; i++) { // 为每个线程创建独立的参数结构体,避免覆盖 ThreadArgs* args = new ThreadArgs(); args->shared = &shared; args->thread_id = i; pthread_create(&tid[i], nullptr, thread_function, (void*)args); } for(int i = 0; i < nthreads; i++) { pthread_join(tid[i], nullptr); } // 销毁同步对象 pthread_mutex_destroy(&shared.bsem); pthread_cond_destroy(&shared.waitTurn); delete[] tid; return 0; }
修复说明
- 避免参数覆盖:为每个线程创建独立的
ThreadArgs结构体,存储自身编号和共享状态指针,确保每个线程拿到正确的编号。 - 移除全局变量:将互斥锁、条件变量和共享的
turn都封装到SharedState局部结构体中,符合题目“仅使用局部变量”的要求。 - 内存管理:线程中动态分配的
ThreadArgs在任务完成后释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Kenny Zhang
相关产品推荐
相关产品推荐

