std::mutex 的 constexpr 构造函数是如何实现的?

2024-01-12

在查看 C++ 参考时std::mutex https://en.cppreference.com/w/cpp/thread/mutex/mutex,我注意到构造函数std::mutex被标记constexpr.

一开始这很令人惊讶,因为我们通常必须进行系统调用(或者pthread_mutex_init() https://linux.die.net/man/3/pthread_mutex_init(POSIX)或CreateMutex() https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexa(Windows)) 来初始化互斥体。然而,仔细检查后,对于 POSIX,可以使用常量PTHREAD_MUTEX_INITIALIZER静态初始化互斥体(可能作为全局变量),尽管我找不到 Windows 的等效项。

然而,即使 POSIX 的静态初始化是背后的原因constexpr构造函数,实现上仍然存在各种未解决的问题:

  1. 在 Windows(或许还有其他非 POSIX 系统)上,可能没有静态初始化互斥体的方法。
  2. 在 C++20 之前,不可能根据编译时是否调用构造函数来拥有不同的代码路径std::is_constant_evaluated() https://en.cppreference.com/w/cpp/types/is_constant_evaluated已添加,因此我们无法确定是否PTHREAD_MUTEX_INITIALIZER or pthread_mutex_init()应该使用。

那么,如何实施constexpr构造函数std::mutex?


在Windows上,可以实现std::mutex as constexpr using SRWLOCK.

不幸的是满了SRWLOCK从 Windows 7 开始可用。它是在 Windows Vista 中引入的,但无法实现try_lock使用它。

Visual Studio 2022 已放弃对 Windows Vista 的支持,因此它可以切换到SRWLOCK,但出于 ABI 兼容性原因,为了兼容到 VS 2015,它仍然使用允许运行时选择同步原语的实现,以避免SRWLOCK在 Win7 之前的版本上。

技术上可以实现std::mutex基于CreateEvent延迟初始化(在 Windows 95 及更高版本中),但这种实现会很复杂且不是最佳的,因为它不会直接使用操作系统原语,也不会允许操作系统知道互斥体。


在 POSIX 上,您可以使用PTHREAD_MUTEX_INITIALIZER无条件地,即使在运行时也是如此。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::mutex 的 constexpr 构造函数是如何实现的? 的相关文章

随机推荐

  • 如何禁用主干历史记录但仍允许基于哈希的路由?

    假设我执行以下操作 单击主页 上的链接并转到 posts 1 触发事件并前往主干路由 posts 1 1 edit 我点击返回 我需要这样做 以便用户最终回到主页 而不是回到 posts 1 所以我需要允许骨干哈希路由工作但不修改历史记录
  • gcc 抑制警告“太小,无法容纳所有值”

    我需要使用范围枚举 以便我可以将它们作为特定类型传递给我们的序列化程序 我已经为枚举成员给出了明确的整数值Enum1 我已将与上面的描述相匹配的两个作用域枚举放入位字段中 enum class Enum1 value1 0x0 value2
  • Recyclerview 按字母顺序滚动条

    我需要实现一个类似于三星音乐应用程序的recyclerview字母滚动条 由于信誉低 我无法发布图像 我已阅读有关此的所有帖子 但我不想要气泡卷轴 我将所有字母表都放在垂直 LinearLayout 中 我想知道如何滚动到特定项目 你可以用
  • 如何在 JavaScript 中使用 x,y 坐标模拟点击?

    是否可以使用给定的坐标来模拟网页中 JavaScript 的点击 您可以派遣一个click事件 尽管这与真正的点击不同 例如 它不能用于欺骗跨域 iframe 文档 使其认为它已被单击 所有现代浏览器都支持document elementF
  • 在Python中按索引从列表中删除元素的简洁方法

    我有一个字符列表和索引列表 myList a b c d toRemove 0 2 我想通过一次操作得到这个 myList b d 我可以做到这一点 但有没有办法做得更快 toRemove reverse for i in toRemove
  • Java FileWriter 和 BufferedWriter 的区别

    它们之间有什么区别 我刚刚学习 Java ATM 但似乎我可以两种方式写入文件 我没有在这里复制 try catch 块 FileWriter file new FileWriter foo txt file write foobar fi
  • 张量流:在多个检查点运行模型评估

    在我当前的项目中 我训练一个模型并每 100 个迭代步骤保存检查点 检查点文件全部保存到同一目录 model ckpt 100 model ckpt 200 model ckpt 300 等 之后 我想根据所有已保存检查点 而不仅仅是最新检
  • WPF 数据网格样式

    有谁知道 有如何将 WPF DataGrid 布局更改为卡片视图或其他任何东西的示例 而不仅仅是行堆栈 结果看起来像这样 替代文本 http iwebthereforeiam com files ScreenShot gif http iw
  • 如何保证训练阶段不会出现OOM?

    标题中的问题已经完成 如何保证训练阶段不会出现OOM 只是一些旁注 根据我的经验 有两种 OOM 情况 一种是模型和小批量所需的内存大于您拥有的内存 在这种情况下 训练阶段将永远不会开始 解决这个问题的解决方案是使用较小的批量大小 尽管如果
  • 使用 Argonaut 进行 Scalaz 验证

    我有一个案例类和伴随对象 case class Person private name String age Int object Person def validAge age Int if age gt 18 age successNe
  • 我们如何在 Android 中播放/缓冲几分钟的视频?

    我需要播放视频的前 2 分钟 使用 onBufferingUpdate 我得到缓冲的百分比 但当 onPrepared 被调用时 我的缓冲百分比为 40 这是一个超过 2 分钟的视频 考虑到我有一个30分钟的视频 有什么办法可以让我只播放
  • PIL / urllib2 - 使用 StringIO 传递文件时无法识别图像文件

    我正在使用 urllib2 从网络下载图像 一旦我下载了它 我想使用一个名为 PIL 的图像模块来用它做一些事情 我不想将文件保存到磁盘然后重新打开 而是使用从内存中传递它StringIO from PIL import Image ima
  • 当 ng-grid 通过 ng-hide 将可见性从不可见更改为可见时,不会重新计算网格宽度

    我有一个带有 ng hide 属性和 width 100 样式的 ng grid div class grid style style display inline block height 300px width 100 div 该网格第
  • Xcode 6 自动完成失败(<<错误类型>>)

    我正在使用 Swift 开发一个应用程序 并且在某个时候我开始遇到奇怪的 Xcode 行为 我不完全记得它是如何发生的 但自动完成功能拒绝工作 并且对于我的所有变量 类型是 gt 我尝试了这里提供的一些解决方案 但它们都不起作用 这种令人沮
  • 如何从pyspark中的数组中提取元素

    我有一个具有以下类型的数据框 col1 col2 col3 col4 xxxx yyyy zzzz 1111 2222 我希望我的输出是以下类型 col1 col2 col3 col4 col5 xxxx yyyy zzzz 1111 22
  • 在每年的每个月下划线 js 组

    这是我的输入 json data id 3 created by 1 created at 2022 01 31T07 00 01 880Z id 2 created by 1 created at 2022 01 31T07 00 01
  • IE 抛出访问被拒绝错误

    我有 2 个项目 相互连接和通信 在 2 个 tomcat 实例上运行 在我的本地 我有 2 个 tomcats 正在运行 在所有不同的浏览器上一切都很好 除了 IE 之外 它说访问被拒绝加载 Javascript 文件 所以我已经包含了一
  • Erlang 列表理解

    我正在测试一个具有两个不等式的表达式来满足列表理解的条件 有没有办法在这里进行赋值而不重复该表达式 下面的代码不起作用 但我希望它能起作用 diagnose Expertise PatientSymptoms gt CertainDisea
  • C++ const public field 与 getter 方法

    我想为某个类的每个对象添加唯一的 ID 在单个会话内 一种解决方案是使用工厂函数来增加一些静态计数器 一个更简单的解决方案是将此计数器添加到类本身 例如 class fooWithUniqueId public fooWithUniqueI
  • std::mutex 的 constexpr 构造函数是如何实现的?

    在查看 C 参考时std mutex https en cppreference com w cpp thread mutex mutex 我注意到构造函数std mutex被标记constexpr 一开始这很令人惊讶 因为我们通常必须进行