我需要一个自旋锁来保护资源。每秒获取几次该锁,并在获取锁时保持约100条指令。换句话说,它几乎总是可用。唯一的例外是,锁每隔几天将保持10毫秒。我觉得有必要在循环中放入一个PAUSE指令或等效指令,以确保在此期间超线程正在等待时10毫秒不会膨胀。我想在可能的情况下使用库函数,但是我想确保该函数从不进入等待状态,而是停留在循环中等待锁。
我已经阅读了C ++标准,并且timed_mutex
似乎可以满足我的要求,但是我无法保证try_lock_for()
会(1)永远不会进入睡眠状态(2)插入暂停。这可能是实施问题。
您是否知道足够的实现建议一个互斥量或锁定类来实现我想要的功能?
最佳答案
我的第一条建议是在走这条路之前,确保您确实需要您认为需要的东西。想要使用自旋锁的主要原因是,在人们知道争用非常少并且不需要某种程度的公平性的情况下,就完全可以减少锁定的开销。您的描述遇到了争用的问题,但是如果仅每秒获得几次锁定,那么互斥锁的开销似乎就没有关系了。
但是如果您确定这是必要的...
通常,如果您需要特定于PAUSE指令的内容,并且有力地保证线程不会直接调用会导致较重睡眠的内容,那么使用C ++标准库函数将是无用的。您根本不会在跨平台上获得类似的保证。但是,这些要求已经不太明确了。例如。无论如何,该线程很可能会在自旋循环内被抢占。如果这是一个问题,那么您将进入实时原语领域。实时操作系统通常确实提供控制级别和可移植原语来执行此类操作。
也就是说,您可以采取两种方法。首先,您可以实现自己的自旋锁。使用std::atomic_flag
并不是特别困难。要半暂停地获得PAUSE功能,您需要使用条件编译,如下所示:
Cross-platform implementation of the x86 pause instruction。 (您可能可以使用x86内在函数支持和_mm_pause()
代替asm语句。)
另一种方法是使用另一个已经实现的库。 Boost的详细信息支持用于提供可移植的yield
函数,该函数在x86和其他平台上执行PAUSE暂停,但是我不确定它是否仍然可用,因为使用C ++合理化了很多线程支持11。英特尔的TBB的spin_mutex
可能会满足需求。 (您可能必须查看实现的内部才能做出决定。)可能还有一些更轻巧的替代品。选择一个预先存在的库通常取决于您的应用程序约束。
如果您要分析性能等,即使没有最终在最终代码中使用它,通常也可以在一个平台上实现自己的性能,因为它可以在进行性能实验时严格控制内部。自旋锁足够小,即使使用PAUSE等,也不需要花费大量时间来编写简单的锁。
编辑:根据平台,pthread_spin_lock
也可能满足要求。
关于c++ - C++:库函数可通过PAUSE产生自旋锁,无需等待?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47623897/