vs2019 C++20 latch

  • 01 latch
  • 02 latch的一个实现

01 latch

<latch> 闩:单次使用的线程屏障。
latch 是 ptrdiff_t 类型的向下计数器,它能用于同步线程。在创建时初始化计数器的值。

线程可能在 latch 上阻塞直至计数器减少到零。没有可能增加或重置计数器,这使得 latch 为单次使用的屏障。

同时调用 latch 的成员函数,除了析构函数,不引入数据竞争。

不同于 std::barrier ,参与线程能减少 std::latch 多于一次。1

方法 作用
latch 不可赋值
count_down 以不阻塞的方式减少计数器
try_wait 测试内部计数器是否等于零
wait 阻塞直至计数器抵达零
arrive_and_wait 减少计数器并阻塞直至它抵达零
max [静态]实现所支持的计数器最大值

latch的参考头文件 std::latch2

namespace std {class latch {public:static constexpr ptrdiff_t max() noexcept;constexpr explicit latch(ptrdiff_t expected);~latch();latch(const latch&) = delete;latch& operator=(const latch&) = delete;void count_down(ptrdiff_t update = 1);bool try_wait() const noexcept;void wait() const;void arrive_and_wait(ptrdiff_t update = 1);private:ptrdiff_t counter;  // 仅用于阐释};
}

02 latch的一个实现

github上面找到一个latch的实现(linux,macos,windows上的实现)。
https://github.com/luncliff/latch

这里贴出windows上面的实现。如果开发又需求,不如先用这个开源的先用起来。
这个latch在windows上面的实现重点使用了 WakeByAddressAll,WaitOnAddress,InterlockedAdd,InterlockedAdd64四个api。
latch.h

#pragma once
#include <cstddef>namespace std {
/*** @defgroup thread.coord* Concepts related to thread coordination, and defines the coordination types `latch` and `barrier`.* These types facilitate concurrent computation performed by a number of threads.*//*** @brief Allows any number of threads to block until an expected number of threads arrive at the latch* @ingroup thread.coord** A `latch` is a thread coordination mechanism that allows any number of threads* to block until an expected number of threads arrive at the `latch`* (via the `count_down` function).** The expected count is set when the `latch` is created.* An individual `latch` is a single-use object;* once the expected count has been reached, the `latch` cannot be reused.** @see N4835, 1571~1572p*/
class latch {public:/*** @brief upper limit on the value of `expected` for constructor of `latch`* @return ptrdiff_t    The maximum value of counter that the implementation supports* @see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1865r1.html* @see /proc/sys/kernel/threads-max*/static constexpr ptrdiff_t max() noexcept {return 32;}public:/*** @brief   Initialize `counter` with `expected`* @param   expected* @pre     `expected >= 0` is true*/constexpr explicit latch(ptrdiff_t expected) noexcept : counter{expected} {}/*** Concurrent invocations of the member functions of `latch` other than its destructor,* do not introduce data races*/~latch() = default;latch(const latch&) = delete;latch& operator=(const latch&) = delete;/*** **Synchronization**:* Strongly happens before the returns from all calls that are unblocked.** **Error Conditions**:* Any of the error conditions allowed for mutex types (32.5.3.2)** @param   update* @pre     `update >= 0` is true, and `update <= counter` is true* @post    Atomically decreses `counter` by `update`.*          If `counter` is equal to zero, unblocks all threads blocked on `*this`* @throw   system_error*/void count_down(ptrdiff_t update = 1) noexcept(false);/*** @return true     `counter` equals zero* @return false    Very low probability of failure from system call*/bool try_wait() const noexcept;/*** If `counter` equals zero, returns immediately.* Otherwise, blocks on `*this` until a call to `count_down` that decrements `counter` to zero** @throw   system_error*/void wait() const noexcept(false);/*** @param   update  input for `count_down`* @see count_down* @see wait*/void arrive_and_wait(ptrdiff_t update = 1) noexcept(false);private:/*** @brief A latch maintains an internal counter** A latch maintains an internal counter that is initialized when the latch is created* Threads can block on the latch object, waiting for counter to be decremented to zero.*/ptrdiff_t counter;
};
} // namespace std

latch_windows.cpp

#include "latch.h"#include <atomic>
#include <system_error>
#include <type_traits>
// clang-format off#include <Windows.h>
#include <synchapi.h>
// clang-format onnamespace std {static_assert(is_copy_assignable_v<latch> == false);
static_assert(is_copy_constructible_v<latch> == false);void latch::arrive_and_wait(ptrdiff_t update) noexcept(false) {this->count_down(update);this->wait();
}void latch::count_down(ptrdiff_t update) noexcept(false) {static_assert(is_same_v<ptrdiff_t, LONG64> || is_same_v<ptrdiff_t, LONG>);if (counter < update)throw system_error{EINVAL, system_category(),"update is greater than counter"};// if not lock-free, rely on InterLocked operationif constexpr (atomic<ptrdiff_t>::is_always_lock_free) {counter -= update;} else if constexpr (is_same_v<ptrdiff_t, LONG>) {InterlockedAdd(reinterpret_cast<LONG*>(&counter),static_cast<LONG>(-update));} else if constexpr (is_same_v<ptrdiff_t, LONG64>) {InterlockedAdd64(reinterpret_cast<LONG64*>(&counter),static_cast<LONG64>(-update));}// counter reached zeroif (counter == 0)WakeByAddressAll(&counter);
}bool latch::try_wait() const noexcept {// if counter equals zero, returns immediatelyif (counter == 0)return true;// blocks on `*this` until a call to count_down that decrements counter to zeroptrdiff_t captured = counter;if (WaitOnAddress(const_cast<ptrdiff_t*>(&counter), &captured,sizeof(ptrdiff_t), INFINITE))return counter == 0;// caller can check `GetLastError` for this casereturn false;
}void latch::wait() const noexcept(false) {while (try_wait() == false) {// case: error from WaitOnAddressif (const auto ec = GetLastError())throw system_error{static_cast<int>(ec), system_category(),"WaitOnAddress"};// case: counter != 0. retry// ...}
}} // namespace std

  1. std::latch ↩︎

  2. 标准库头文件<latch> ↩︎

C++20 latch相关推荐

  1. 【性能优化】 之 RAC架构性能优化

    1.演示通过设置不同的服务,达到RAC业务分割的效果.<br> 2.对比将并行操作放在RAC多个节点执行和单个节点执行的效率.<br> 3.演示RAC的cache fusion ...

  2. 【转载】Oracle ACE总监对Oracle 12c的一些新特性总结

    2019独角兽企业重金招聘Python工程师标准>>> 本文是Oracle ACE总监Syed Jaffer Hussain对Oracle数据库12c的一些新特性总结,包括数据库管理 ...

  3. 利用php屏蔽海外ip访问,高效实现

    <?php/*** 屏蔽海外ip访问* 使用ip2long函数得到ip转为整数的值,判断值是否在任一一个区间中* 以下是所有国内ip段* 调用方法:IschinaIp($ALLIPS)* 返回值 ...

  4. oracle 闩机制,Oracle latch闩原理示意图

    还是搞不懂oracle中latch 闩的原理吗?那么来看看这个图 以及下面这段代码如何? Function Get_Latch(latch_name,mode) { If Mode eq 'immed ...

  5. PMON failed to acquire latch, see PMON dump

    前几天,一台Oracle数据库(Oracle Database 10g Release 10.2.0.4.0 - 64bit Production)监控出现"PMON failed to a ...

  6. Esper 20章 优化

    为什么80%的码农都做不了架构师?>>>    20 优化 esper为了处理高速的生成力已经高度优化,并且接收事件和输出结果低延迟. esper还可以进一步最大化可测使用在 软实时 ...

  7. java barrier_Java - Latch和Barrier的区别

    之所以把Latch与Barrier放在一起比较是因为他们给人一种相似的感觉. 他们都是阻塞一些行为直至某个事件发生,但Latch是等待某个事件发生,而Barrier是等待线程. 先比较一下JCIP中对 ...

  8. C++20 系列(一)- Hello C++20

    系列文章目录 C++20 系列(一)- Hello C++20 四大模块 毋庸置疑,C++20 将会和 C++11 一样,从根本上改变我们的 C++ 编程方式.C++20 中引入了四大模块: Rang ...

  9. 通过案例学调优之--和 LOG BUFFER 相关的主要 Latch

    4.1.和 LOG BUFFER 相关的主要 Latch  有:  Latch:Redo Copy       Latch:Redo Allocation Latch 4.2 当一个进程在修改数据时候 ...

  10. Latch free等待事件

    原文:oracle waitinterface-a practical guide to performance diagnostics & tuning Richmond shee Kirt ...

最新文章

  1. 适配器模式原理及实例介绍
  2. js数组中的引用类型
  3. 默认库“LIBCMTD”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
  4. codeforces——Little Pony and Sort by Shift
  5. feign使用_Feign:介绍与使用
  6. cdev_alloc和cdev_init
  7. 人生这场牌,怎么打才是最优解?
  8. Python验证码识别初探(tesserocr库)
  9. QProcess解决无交互输入密码问题
  10. 最全常用正则表达式大全
  11. win10电脑怎么将html网页做成壁纸,win10系统怎么在电脑桌面上创建网页的快捷方式...
  12. CAD-Cass小结(5)————WIN10安装并运行CAD2006及Cass7.0
  13. win10计算机禁用用户账户控制,win10用户账户控制怎么关闭_用户账户控制如何解除win10-win7之家...
  14. windows10下使用mencoder将y4m文件转换为YUV文件
  15. 黑客白皮书:如何成为一名黑客(附FAQ)
  16. 极狐GitLab硬实力助力中国开源生态建设
  17. 谈谈AssetStore及其脱离Unity下载方法
  18. python3 jason 、pickle 和cpickle
  19. 传Snapchat母公司Snap拟于3月在纽交所IPO上市
  20. CSP认证:行车路线

热门文章

  1. 怎样低成本的实现网页在移动端的适配
  2. 数据结构(主席树,Bit):XTU 1247/COGS 2344. pair-pair
  3. 机器阅读理解任务综述
  4. 重发布,路由策略实验
  5. 使用scrapy框架爬取腾讯招聘信息
  6. 吴军老师的《计算之魂》部分重点摘要
  7. qml中Popup元素的 aboutToShow和 opened()的区别
  8. PuTTY key format too new怎么解决?
  9. Kuangbin 带你飞-线段树专题 题解
  10. 斜挎包长度到哪里合适_一般斜挎包长多少厘米_身高170斜挎包带长