线程屏障与P6进程线程管控异常:代码陷入死循环技术求助
线程屏障死循环问题排查与修复
需求说明
- 线程T6.13必须在包含自身在内的6个线程同时运行时才能结束
- 进程主线程T6.0不能早于其他43个线程终止
- 任意时刻,进程P6中同时运行的线程(不含主线程)最多为6个
问题现象
代码运行到某一阶段时界面停滞,陷入死循环。
原始代码
TH_STRUCT_2 *param = (TH_STRUCT_2*)arg; sem_wait(param->semaphore); pthread_mutex_lock(param->lock); (*param->active_threads)++; int thread_num = param->thread_num; pthread_mutex_unlock(param->lock); sem_post(param->start_semaphore); info(BEGIN, 6, thread_num); if(thread_num == 13) { printf("%d\n", (*param->active_threads) ); pthread_mutex_lock(param->lock); while(*param->active_threads < 6) { pthread_cond_wait(param->cond, param->lock); } pthread_mutex_unlock(param->lock); } pthread_mutex_lock(param->lock); (*param->active_threads)--; pthread_mutex_unlock(param->lock); info(END, 6, thread_num); if(thread_num == 13 && *param->active_threads == 1) { pthread_cond_broadcast(param->cond); } sem_post(param->semaphore); return NULL;
核心问题分析
等待时机错误:T6.13的等待逻辑放在
info(BEGIN)之后,此时其他线程可能已经开始执行active_threads--操作,导致活跃线程数永远凑不到6,触发死循环。T6.13的核心要求是在6个线程同时运行时结束,意味着它必须等活跃线程数达到6后,才能执行结束动作(即active_threads--)。条件触发逻辑无效:当前
pthread_cond_broadcast的触发条件是active_threads == 1,这时候T6.13的等待逻辑早已执行完毕,广播信号完全起不到唤醒作用。正确的触发时机应该是当活跃线程数刚达到6的时候。主线程同步缺失:代码未处理主线程等待所有子线程终止的逻辑,违反了“主线程不得早于其他43个线程终止”的要求。
修复后的代码
TH_STRUCT_2 *param = (TH_STRUCT_2*)arg; sem_wait(param->semaphore); pthread_mutex_lock(param->lock); (*param->active_threads)++; int thread_num = param->thread_num; // 活跃线程数刚增加到6时,立即广播唤醒T6.13 if(*param->active_threads == 6) { pthread_cond_broadcast(param->cond); } pthread_mutex_unlock(param->lock); sem_post(param->start_semaphore); info(BEGIN, 6, thread_num); // T6.13等待活跃线程数达到6,才允许执行后续的结束逻辑 if(thread_num == 13) { pthread_mutex_lock(param->lock); while(*param->active_threads < 6) { pthread_cond_wait(param->cond, param->lock); } pthread_mutex_unlock(param->lock); } // 执行结束动作,减少活跃线程数 pthread_mutex_lock(param->lock); (*param->active_threads)--; pthread_mutex_unlock(param->lock); info(END, 6, thread_num); sem_post(param->semaphore); return NULL;
主线程同步补充
为了满足“主线程不得早于其他43个线程终止”的要求,主线程在创建完所有子线程后,需要逐个等待子线程结束:
// 假设threads是存储所有子线程ID的数组 for (int i = 0; i < 43; i++) { pthread_join(threads[i], NULL); }
内容的提问来源于stack exchange,提问作者locki
相关产品推荐
相关产品推荐

