在查看 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
构造函数,实现上仍然存在各种未解决的问题:
- 在 Windows(或许还有其他非 POSIX 系统)上,可能没有静态初始化互斥体的方法。
- 在 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(使用前将#替换为@)