当前位置:首页 > 公众号精选 > CPP开发者
[导读]之前整理过一篇C20新特性的文章全网首发!!C20新特性全在这一张图里了,里面提到过latch、barrier和semaphore,但是没有详细介绍过三者的作用和区别,这里详细介绍下。latch这个可能大多数人都有所了解,这就是我们经常会用到的CountDownLatch。用于使...

之前整理过一篇C 20新特性的文章全网首发!!C 20新特性全在这一张图里了,里面提到过latch、barrier和semaphore,但是没有详细介绍过三者的作用和区别,这里详细介绍下。

latch

这个可能大多数人都有所了解,这就是我们经常会用到的CountDownLatch。用于使一个线程先阻塞,等待其他线程完成各自的工作后再继续执行。

CountDownLatch是通过计数器实现,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后等待的线程就可以打断阻塞去继续执行任务。

自己之前实现过一个CountDownLatch,源码大概这样:

CountDownLatch::CountDownLatch(int32_t count) : count_(count) {}

void CountDownLatch::CountDown() {  
    std::unique_lock lock(mutex_);    
    --count_;    
    if (count_ == 0) {       
        cv_.notify_all();   
    }
}
void CountDownLatch::Await(int32_t time_ms) {   
    std::unique_lock lock(mutex_);    
    while (count_ > 0) {       
        if (time_ms > 0) {        
            cv_.wait_for(lock, std::chrono::milliseconds(time_ms));       
        } else {           
            cv_.wait(lock);       
        }   
    }
}

int32_t CountDownLatch::GetCount() const {   
    std::unique_lock lock(mutex_); 
    return count_;
}

barrier

许多线程在阻塞点阻塞,当到达阻塞点的线程达到一定数量时,会执行完成的回调,然后解除所有相关线程的阻塞,然后重置线程计数器,继续开始下一阶段的阻塞。

假设有很多线程并发执行,并在一个循环中执行一些计算。进一步假设一旦这些计算完成,需要在线程开始其循环的新迭代之前对结果进行一些处理。

看以下示例代码(摘自cppreference):

#include 
#include 
#include 
#include 
#include  

int main() {  
  const auto workers = { "anil""busara""carl" };   
  
  auto on_completion = []() noexcept {    
    // locking not needed here    
    static auto phase = "... done\n" "Cleaning up...\n";    
    std::cout << phase;   
    phase = "... done\n";  
  };  
  std::barrier sync_point(std::ssize(workers), on_completion);  
  
  auto work = [
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭