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

成对Barrier线程同步:同色线程配对返回匹配ID的实现问题

问题分析

现有代码的核心问题出在共享状态的重置时机、信号量的复用冲突两个方面,具体如下:

  • 全局信号量a1/a2/barr没有按颜色隔离,同时多组同色线程进入时会互相抢占信号量,导致配对id错位
  • count[0]的计数逻辑没有正确闭环:第一对配对完成后的状态没有安全重置,第三、第四个线程进入时计数逻辑会出现越界或者配对混乱
  • 非临界区的map读写没有保护:else分支中修改map[0][1]和重置count[0]时没有加锁,可能和其他线程的写入操作冲突
修正实现思路

每个颜色独立维护一套状态变量,避免不同颜色、不同配对批次的线程互相干扰,单种颜色的状态变量包含:

  1. 互斥信号量lock:保护计数和配对id数组的读写
  2. 同步信号量rendezvous:实现两个线程的会合等待
  3. 计数变量count:记录当前进入的同色线程数量
  4. 配对存储数组pair_ids:暂存两个配对线程的id
初始化注意事项

使用前需要对每个颜色的状态变量进行初始化,示例初始化代码如下:

// 假设共3种颜色,可按实际需求调整数量
typedef struct {
    sem_t lock;
    sem_t rendezvous;
    int count;
    int pair_ids[2];
} ColourState;
ColourState states[3] = {0};

// 初始化调用逻辑
for (int i = 0; i < 3; i++) {
    sem_init(&states[i].lock, 0, 1);
    sem_init(&states[i].rendezvous, 0, 0);
    states[i].count = 0;
}
修正后函数实现
int pack_thread(int colour, int id) {
    // 颜色映射为数组下标,可按实际规则调整
    int idx = colour - 1;
    ColourState *s = &states[idx];

    sem_wait(&s->lock);
    int pos = s->count;
    s->pair_ids[pos] = id;
    s->count++;

    if (s->count == 1) {
        // 第一个到达的线程,释放锁后等待第二个线程会合
        sem_post(&s->lock);
        sem_wait(&s->rendezvous);
        return s->pair_ids[1 - pos];
    } else {
        // 第二个到达的线程,唤醒等待的第一个线程,重置状态后返回
        int ret = s->pair_ids[1 - pos];
        s->count = 0;
        sem_post(&s->rendezvous);
        sem_post(&s->lock);
        return ret;
    }
}
逻辑说明
  • 互斥信号量lock保证同一时间只有一个线程修改对应颜色的计数和id存储,避免竞态
  • 第一个进入的线程记录id后释放锁,阻塞等待会合信号
  • 第二个进入的线程记录id后,直接唤醒等待的第一个线程,同时重置计数,准备下一批同色线程配对
  • 两个线程分别返回对方存储的id,不存在交叉读写的问题,多对线程顺序进入也不会出现id错位

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 00:15:08