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

线程屏障与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;

核心问题分析

  1. 等待时机错误:T6.13的等待逻辑放在info(BEGIN)之后,此时其他线程可能已经开始执行active_threads--操作,导致活跃线程数永远凑不到6,触发死循环。T6.13的核心要求是在6个线程同时运行时结束,意味着它必须等活跃线程数达到6后,才能执行结束动作(即active_threads--)。

  2. 条件触发逻辑无效:当前pthread_cond_broadcast的触发条件是active_threads == 1,这时候T6.13的等待逻辑早已执行完毕,广播信号完全起不到唤醒作用。正确的触发时机应该是当活跃线程数刚达到6的时候。

  3. 主线程同步缺失:代码未处理主线程等待所有子线程终止的逻辑,违反了“主线程不得早于其他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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:58:12