我有一些代码在一个每秒激活的线程中使用一个int(int[]
)数组。
我使用lock()
中的std::mutex
来锁定此主题中的数组。
但我想知道是否有办法创建原子数组(或向量)以避免使用互斥锁?我尝试了几种方法,但编译器总是以某种方式抱怨?
我知道有一种方法可以创建一个原子数组,但这不一样。
答案 0 :(得分:37)
实际上,在CPU级别,有一些指令可以自动更新int
,一个好的编译器会将这些指令用于std::atomic<int>
。相比之下,没有任何指令可以自动更新int的向量(对于我所知道的任何架构),因此得到是某种某种互斥体。你不妨让它成为你的互斥体。
对于尚未使用互斥锁编写代码的未来读者:
您无法创建std::atomic
int[10]
,因为这会导致返回数组的功能 - 而您无法获得这些功能。您可以做的事情是std::atomic<std::array<int,10>>
int main()
{
std::atomic<std::array<int,10>> myArray;
}
请注意,编译器/库将在底层创建一个互斥锁以使其成为原子。进一步注意,这并不是你想要的。它允许您以原子方式设置整个数组的值。
它不会允许您读取整个数组,更新一个元素,并以原子方式写回整个数组。
读取和写入将是单独原子的,但另一个线程可以介入读取和写入之间。
你需要互斥锁!
答案 1 :(得分:6)
您可以将数组放在原子中,但不能直接放入。与其他答案解释一样,您可以使用std::array
。我回答this question并解释了如何为结构做类似的事情。
话虽如此并解释了技术可行性,但我必须告诉你一些事情:
原子变量的力量来自于某些处理器可以用一条指令执行操作的事实。 C ++编译器将尝试在一条指令中进行原子操作。如果失败,它将启动总线锁,这类似于全局锁定所有内容,直到该阵列更新为止。它相当于一个锁定程序中所有变量的互斥锁。如果您担心表现,请不要这样做!
因此,对于您的情况,互斥量并不是一个坏主意。至少你可以控制什么是关键并提高性能。