您现在的位置是:亿华云 > 数据库
C++20新特性的小细节,你掌握了吗?
亿华云2025-10-03 18:20:42【数据库】6人已围观
简介本文转载自微信公众号「程序喵大人」,作者程序喵大人。转载本文请联系程序喵大人公众号。之前我整理过一篇C++20新特性的文章全网首发!!C++20新特性全在这一张图里了,里面提到过latch、barri
本文转载自微信公众号「程序喵大人」,新细节作者程序喵大人。特性转载本文请联系程序喵大人公众号。掌握
之前我整理过一篇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 = "... done\n" "Cleaning up...\n"; std::cout << phase; phase = "... done\n"; }; std::barrier sync_point(std::ssize(workers), on_completion); auto work = [&](std::string name) { std::string product = " " + name + " worked\n"; std::cout << product; // ok, op<< call is atomic sync_point.arrive_and_wait(); product = " " + name + " cleaned\n"; 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 ... donesemaphore
信号量,这个估计大家都很熟悉,本质也是个计数器,主要有两个方法:
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 signal\n"; // response message using namespace std::literals; std::this_thread::sleep_for(3s); std::cout << "[thread] Send the signal\n"; // message smphSignalThreadToMain.release(); } int main() { std::thread thrWorker(ThreadProc); std::cout << "[main] Send the signal\n"; // message smphSignalMainToThread.release(); smphSignalThreadToMain.acquire(); std::cout << "[main] Got the signal\n"; // response message thrWorker.join(); } 输出如下: [main] Send the signal [thread] Got the signal [thread] Send the signal [main] Got the signal信号量也可以当作条件变量使用,这个我估计大家应该知道怎么做。
打完收工。
高防服务器很赞哦!(947)
相关文章
- 脱碳数据中心:基础设施的未来
- 最后提醒我们,域名到期后要及时更新域名,否则可能会丢掉域名,每次抢先注册都不会成功。
- 4、club娱乐
- 4、参加域名拍卖会
- NVIDIA推出各项举措:探索DPU应用场景,赋能开发者加速创新
- 2、根据用户基础选择访问提供程序。由于互联问题的存在,接入商的选择也非常重要,如果用户群主要在联通,尽量选择联通接入较好的接入商,如果用户群主要在电信,那么选择电信接入较好的接入商。如果用户组位于国家/地区,则选择更好的访问提供程序进行交互。
- 一下域名,看有没有显示出你所解析的IP,如果有,就说明解析是生效的;如果没有,就说明解析是不生效的。
- 因为域名解析需要同步到DNS根服务器,而DNS根服务器会不定时刷,只有DNS根服务器刷新后域名才能正常访问,新增解析一般会在10分钟左右生效,最长不会超过24小时,修改解析时间会稍微延长。
- 普洛斯数据中心为某互联网头部平台打造的首个液冷智算数据中心正式交付运营
- 尽量不要在域名中出现特殊字符,这样的域名很容易导致访问者输入错误,同时给人留下不专业的印象,降低网站的可信度,并流失大量潜在客户。