是否可以在 C++ 中创建原子向量或数组?
Is it possible to create an atomic vector or array in C++?
我有一些代码在每秒激活的线程中使用一个 int (int[]
) 数组。
我使用 std::mutex
中的 lock()
在这个线程中锁定这个数组。
但是我想知道是否有一种方法可以创建原子数组(或向量)来避免使用互斥量?我尝试了几种方法,但编译器总是以某种方式抱怨?
我知道有一种方法可以创建原子数组,但这不一样。
实际上,在 CPU 级别,有一些指令可以自动更新 int
,一个好的编译器会将这些指令用于 std::atomic<int>
。相比之下,没有任何指令可以自动更新 int 向量(对于我所知道的任何体系结构),因此 got 是某种互斥锁。你不妨让它成为你的互斥量。
对于尚未使用互斥锁编写代码的未来读者:
您不能创建 int[10]
的 std::atomic
,因为这会导致 returns 一个数组的函数 - 而您不能拥有这些。你可以做的是std::atomic<std::array<int,10>>
int main()
{
std::atomic<std::array<int,10>> myArray;
}
请注意,compiler/library 将在后台创建一个互斥锁以使其成为原子。进一步注意,这不会做你想要的。它允许您以原子方式设置整个数组的值。
它不允许读取整个数组,更新一个元素,然后自动写回整个数组。
读取和写入将是单独的原子操作,但另一个线程可以介于读取和写入之间。
你需要互斥体!
您可以将数组放入原子中,但不能直接放入。就像其他答案解释一样,您可以使用 std::array
。我回答了 并解释了如何为结构做类似的事情。
说了这么多并解释了技术可行性,我还得告诉你一些事情:
请不要那样做
原子变量的力量来自这样一个事实,即一些处理器可以用一条指令完成它们的操作。 C++ 编译器将尝试使您的原子操作在一条指令中发生。如果失败,它将启动 总线锁定 ,这就像对所有内容进行全局锁定,直到更新该数组。它相当于一个互斥锁,可以锁定你程序中的所有变量。如果您担心性能,请不要那样做!
因此对于您的情况,互斥体不是一个坏主意。至少你可以控制关键的东西并提高性能。
我有一些代码在每秒激活的线程中使用一个 int (int[]
) 数组。
我使用 std::mutex
中的 lock()
在这个线程中锁定这个数组。
但是我想知道是否有一种方法可以创建原子数组(或向量)来避免使用互斥量?我尝试了几种方法,但编译器总是以某种方式抱怨?
我知道有一种方法可以创建原子数组,但这不一样。
实际上,在 CPU 级别,有一些指令可以自动更新 int
,一个好的编译器会将这些指令用于 std::atomic<int>
。相比之下,没有任何指令可以自动更新 int 向量(对于我所知道的任何体系结构),因此 got 是某种互斥锁。你不妨让它成为你的互斥量。
对于尚未使用互斥锁编写代码的未来读者:
您不能创建 int[10]
的 std::atomic
,因为这会导致 returns 一个数组的函数 - 而您不能拥有这些。你可以做的是std::atomic<std::array<int,10>>
int main()
{
std::atomic<std::array<int,10>> myArray;
}
请注意,compiler/library 将在后台创建一个互斥锁以使其成为原子。进一步注意,这不会做你想要的。它允许您以原子方式设置整个数组的值。
它不允许读取整个数组,更新一个元素,然后自动写回整个数组。
读取和写入将是单独的原子操作,但另一个线程可以介于读取和写入之间。
你需要互斥体!
您可以将数组放入原子中,但不能直接放入。就像其他答案解释一样,您可以使用 std::array
。我回答了
说了这么多并解释了技术可行性,我还得告诉你一些事情:
请不要那样做
原子变量的力量来自这样一个事实,即一些处理器可以用一条指令完成它们的操作。 C++ 编译器将尝试使您的原子操作在一条指令中发生。如果失败,它将启动 总线锁定 ,这就像对所有内容进行全局锁定,直到更新该数组。它相当于一个互斥锁,可以锁定你程序中的所有变量。如果您担心性能,请不要那样做!
因此对于您的情况,互斥体不是一个坏主意。至少你可以控制关键的东西并提高性能。