在futex系统调用中使用std::atomic

在 C++20 中,我们能够在原子变量上休眠,等待它们的值改变。我们通过使用std::atomic::wait方法来做到这一点。

不幸的是,虽然wait已经标准化,wait_forwait_until不是。这意味着我们不能在超时的原子变量上睡觉。

无论如何,使用 Windows上的WaitOnAddress和Linux 上的futex系统调用在幕后实现原子变量睡眠。

解决上述问题(无法在具有超时的原子变量上休眠),我可以在 Windows 上将内存地址传递std::atomic给 toWaitOnAddress并且它将(有点)在没有 UB 的情况下工作,因为该函数void*作为参数获取,并且强制转换std::atomic<type>为有效void*

在 Linux 上,不清楚是否可以std::atomicfutex. futex得到无论是uint32_t*int32_t*(取决于你读这手册),铸造std::atomic<u/int>u/int*为UB。另一方面,手册说

uaddr 参数指向 futex 字。 在所有平台上,futex 都是四字节整数,必须在四字节边界上对齐。在 futex_op 参数中指定要对 futex 执行的操作;val 是一个值,其含义和目的取决于 futex_op。

提示alignas(4) std::atomic<int>应该有效,只要类型具有 4 个字节的大小和 4 的对齐方式,它是哪种整数类型并不重要。

此外,我已经看到很多地方实现了这种结合原子和 futexes 的技巧,包括boost和TBB。

那么以非 UB 方式在具有超时的原子变量上睡眠的最佳方法是什么?我们是否必须使用操作系统原语来实现我们自己的原子类才能正确实现它?

(存在混合原子和条件变量等解决方案,但不是最优的)

以上是在futex系统调用中使用std::atomic的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>