加入收藏 | 设为首页 | 会员中心 | 我要投稿 大连站长网 (https://www.0411zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

C++20新特性的小细节,你学会了吗?

发布时间:2021-11-05 02:51:08 所属栏目:语言 来源:互联网
导读:之前我整理过一篇C++20新特性的文章全网首发!!C++20新特性全在这一张图里了,里面提到过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<std::mutex> lock(mutex_);      --count_;      if (count_ == 0) {          cv_.notify_all();      }  }    void CountDownLatch::Await(int32_t time_ms) {      std::unique_lock<std::mutex> 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<std::mutex> lock(mutex_);      return count_;  }  barrier 许多线程在阻塞点阻塞,当到达阻塞点的线程达到一定数量时,会执行完成的回调,然后解除所有相关线程的阻塞,然后重置线程计数器,继续开始下一阶段的阻塞。   假设有很多线程并发执行,并在一个循环中执行一些计算。进一步假设一旦这些计算完成,需要在线程开始其循环的新迭代之前对结果进行一些处理。   看以下示例代码(摘自cppreference):   #include <barrier>  #include <iostream>  #include <string>  #include <thread>  #include <vector>     int main() {    const auto workers = { "anil", "busara", "carl" };       auto on_completion = []() noexcept {       // locking not needed here      static auto phase = "... donen" "Cleaning up...n";      std::cout << phase;      phase = "... donen";    };    std::barrier sync_point(std::ssize(workers), on_completion);       auto work = [&](std::string name) {      std::string product = "  " + name + " workedn";      std::cout << product;  // ok, op<< call is atomic      sync_point.arrive_and_wait();         product = "  " + name + " cleanedn";      std::cout << product;      sync_point.arrive_and_wait();    };       std::cout << "Starting...n";    std::vector<std::thread> threads;    for (auto const& worker : workers) {      threads.emplace_back(work, worker);    }    for (auto& thread : threads) {      thread.join();    }  }  可能的输出如下:   Starting...    anil worked    carl worked    busara worked  ... done  Cleaning up...    busara cleaned    carl cleaned    anil cleaned  ... done  semaphore 信号量,这个估计大家都很熟悉,本质也是个计数器,主要有两个方法:   acquire():递减计数器,当计数器为零时阻塞,直到计数器再次递增。   release():递增计数器(可传递具体数字),并解除在acquire调用中的线程的阻塞。   示例代码如下:   #include <iostream>  #include <thread>  #include <chrono>  #include <semaphore>    std::binary_semaphore    smphSignalMainToThread(0),    smphSignalThreadToMain(0);     void ThreadProc() {      smphSignalMainToThread.acquire();    std::cout << "[thread] Got the signaln"; // response message    using namespace std::literals;    std::this_thread::sleep_for(3s);       std::cout << "[thread] Send the signaln"; // message    smphSignalThreadToMain.release();  }     int main() {    std::thread thrWorker(ThreadProc);    std::cout << "[main] Send the signaln"; // message       smphSignalMainToThread.release();       smphSignalThreadToMain.acquire();       std::cout << "[main] Got the signaln"; // response message    thrWorker.join();  }  输出如下:  [main] Send the signal  [thread] Got the signal  [thread] Send the signal  [main] Got the signal  信号量也可以当作条件变量使用,这个我估计大家应该知道怎么做。   打完收工。

(编辑:大连站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!