自动读取值的函数
Functions to atomically read a value?
我目前正在使用原子读和写,并且在我的理解中遇到了瓶颈。我理解写入变量(例如通过增量)必须是原子的,但我不确定是否读取变量。
考虑Windows上的_InterlockedExchangeAdd
,或Linux上的__sync_add_and_fetch
。我找不到自动检索正在更新的值的函数。现在我已经做了我的研究之前张贴在这里和c++读写int原子吗?告诉我读操作不是原子的
1)如果我使用上面的函数,我如何自动地读取值,如果从函数返回它?
2)如果我不想使用这些函数,只是想在每次写我的"原子"变量之前锁定互斥锁,在检索变量的当前值的函数中,我需要先锁定互斥锁,复制当前值,解锁互斥锁然后返回副本吗?
编辑
我使用的编译器不能访问原子头文件,因此必须使用这些api
你找不到答案,因为没有一种方法可以做到(a)快速和(b)可移植。这取决于:c++或C,编译器,编译器版本,编译器设置,库,架构…这样的例子不胜枚举。
起始点:
- 如果你有访问标准原子或然后使用
atomic_load()
-它是便携式和快速。 - 如果你没有标准的原子,那么使用CAS。例如,在Windows上,它将是
_InterlockedCompareExchange(,0,0)
。见https://msdn.microsoft.com/en-us/library/ms686355 (VS.85) . aspx。在Linux上是__sync_val_compare_and_swap(, 0, 0)
。参见https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Atomic-Builtins.html。 - 如果你想使用直接赋值,那么你应该向知道代码将在哪里运行的专家咨询。
我碰巧有一段汇编程序代码,它可以解释为什么CAS是一个合理的选择。这是C, i86,微软编译器VS2015, Win64目标:
volatile long debug_x64_i = std::atomic_load((const std::_Atomic_long *)&my_uint32_t_var);
00000001401A6955 mov eax,dword ptr [rbp+30h]
00000001401A6958 xor edi,edi
00000001401A695A mov dword ptr [rbp-0Ch],eax
debug_x64_i = _InterlockedCompareExchange((long*)&my_uint32_t_var, 0, 0);
00000001401A695D xor eax,eax
00000001401A695F lock cmpxchg dword ptr [rbp+30h],edi
00000001401A6964 mov dword ptr [rbp-0Ch],eax
debug_x64_i = _InterlockedOr((long*)&my_uint32_t_var, 0);
00000001401A6967 prefetchw [rbp+30h]
00000001401A696B mov eax,dword ptr [rbp+30h]
00000001401A696E xchg ax,ax
00000001401A6970 mov ecx,eax
00000001401A6972 lock cmpxchg dword ptr [rbp+30h],ecx
00000001401A6977 jne foo+30h (01401A6970h)
00000001401A6979 mov dword ptr [rbp-0Ch],eax
volatile long release_x64_i = std::atomic_load((const std::_Atomic_long *)&my_uint32_t_var);
00000001401A6955 mov eax,dword ptr [rbp+30h]
release_x64_i = _InterlockedCompareExchange((long*)&my_uint32_t_var, 0, 0);
00000001401A6958 mov dword ptr [rbp-0Ch],eax
00000001401A695B xor edi,edi
00000001401A695D mov eax,dword ptr [rbp-0Ch]
00000001401A6960 xor eax,eax
00000001401A6962 lock cmpxchg dword ptr [rbp+30h],edi
00000001401A6967 mov dword ptr [rbp-0Ch],eax
release_x64_i = _InterlockedOr((long*)&my_uint32_t_var, 0);
00000001401A696A prefetchw [rbp+30h]
00000001401A696E mov eax,dword ptr [rbp+30h]
00000001401A6971 mov ecx,eax
00000001401A6973 lock cmpxchg dword ptr [rbp+30h],ecx
00000001401A6978 jne foo+31h (01401A6971h)
00000001401A697A mov dword ptr [rbp-0Ch],eax
你使用互斥锁的计划(2)是正确的。
好运。
相关文章:
- C++从 std::async 函数读取命名空间中的全局变量标志
- 使用函数读取文件.txt中的矩阵
- 函数读取最大和min int值,并用文本字符串返回
- 如何使用 void 函数读取名字和姓氏
- 使用 getline 函数读取文件,但第一列显示为空
- 如何从函数读取返回值
- 使用函数C++读取文件
- 使用比较运算符和字符串比较函数读取文本文件的子部分时出现问题
- 其中是升压套接字的函数读取
- 单链表添加函数-读取访问冲突
- 在使用 imread 函数读取 jpg 文件时,是否有任何可能的理由在 opencv 中遇到一些困难
- 使用成员函数读取C++中的文件
- 是否可以使用stdio函数读取Windows应用商店应用程序中的资产
- 函数读取输入并运行函数两次
- C++ 在 main 中打开一个文件以供函数读取
- 函数读取进程内存不断返回ERROR_PARTIAL_COPY
- 如何确定未格式化输入函数读取的字符数
- 为什么我不能使用此 scanf 函数读取输入字符串?
- 使用递归函数读取txt文件的行
- 函数读取二进制文件使用v8