代码之家  ›  专栏  ›  技术社区  ›  ynn

使用“std::sync::Barrier”时如何选择线程引线?

  •  0
  • ynn  · 技术社区  · 1 年前

    我在学习 std::sync::Barrier 在Rust中。

    根据的文件 wait() 方法

    pub fn wait(&self) -> BarrierWaitResult

    在所有线程重新组合一次后,屏障可以重新使用,并且可以连续使用。

    单个(任意)线程将接收 BarrierWaitResult 返回 true 从…起 BarrierWaitResult::is_leader() 从该函数返回时,所有其他线程将收到一个返回的结果 false 从…起 BarrierWaitResult::is_leader() .

    我有两个问题:

    • 领导者是如何选择的?

    • 如果我们重复使用屏障,那么在第一次使用中选择的领导者是否总是在第二次使用中被选为领导者?(据我测试,这是真的。) 编辑:答案是否定的( playground ).

    1 回复  |  直到 1 年前
        1
  •  1
  •   Iris    1 年前

    来自 implementation 属于 wait() :

    pub fn wait(&self) -> BarrierWaitResult {
        let mut lock = self.lock.lock().unwrap();
        let local_gen = lock.generation_id;
        lock.count += 1;
        if lock.count < self.num_threads {
            let _guard =
                self.cvar.wait_while(lock, |state| local_gen == state.generation_id).unwrap();
            BarrierWaitResult(false)
        } else {
            lock.count = 0;
            lock.generation_id = lock.generation_id.wrapping_add(1);
            self.cvar.notify_all();
            BarrierWaitResult(true)
        }
    }
    

    它似乎保留了所有线程的计数。当一个给定的线程聚合时,如果它是最后一个线程,它将成为前导线程( BarrierWaitResult(true) ),否则它将成为非领导者( BarrierWaitResult(false) ).