赢得32位INT类型的API互锁操作
-
30-09-2019 - |
题
如果有:
__int32 some_var = 0;
什么是最好的(如果有)打电话的方法 InterlockedExchange
, InterlockedIncrement
以及其他需要的互锁功能 LONG*
为了 some_var
?
因为有保证 LONG
在任何窗户上都是32位,可能只是安全地通过 (long*) some_var
. 。但是,在我看来,这很丑陋,我找不到确认它是安全的。
注意,我无法将类型更改为 long
因为它不是便携式的。我完全需要32位类型。
更新: 提供便携式原子操作的图书馆的一些研究表明,没有人对铸造感到困惑。一些例子:
typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_fn)
(apr_uint32_t volatile *,
apr_uint32_t);
APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
{
#if (defined(_M_IA64) || defined(_M_AMD64))
return InterlockedExchangeAdd(mem, val);
#elif defined(__MINGW32__)
return InterlockedExchangeAdd((long *)mem, val);
#else
return ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, val);
#endif
}
AO_INLINE AO_t
AO_fetch_and_sub1_full (volatile AO_t *p)
{
return _InterlockedDecrement64((LONGLONG volatile *)p) + 1;
}
解决方案
做就是了 assert(sizeof(LONG) == sizeof(some_var))
并且只有当断言失败时就担心问题。 Yagni. 。只要主张成立,您就可以使用 reinterpret_cast<LONG*>(&some_var)
.
其他提示
好吧,这是一块岩石和一个艰难的地方。原子增量是重型平台实施细节。这就是为什么首先存在长期类型的原因。从现在开始20或50年的一些未来操作系统可能会重新定义该类型。例如,256位核心是常见的,而原子增量的工作方式也有所不同。谁知道。
如果您想编写真正的便携式代码,则应使用真正的便携式类型。喜欢长。这将是Microsoft的负担,而不是您的负担。
这将是一个32位的整数,很长一段时间,我建议您不必担心。
您最好将类型更改为长时间,剩下便携性,因为整个“互锁”原子操作家族也是 无法便携.
顺便说一句,作为旁注,我认为互锁支持整数超负荷。也许那只是在.net中。
好, __int32
不是便携式类型 任何一个. 。因此,我解决问题的建议是使用Typedef。在窗户上,您可以做:
typedef LONG my_int32;
...安全地将指针传递给这种类型 InterlockedExchange()
. 。在其他系统上,使用其中的32位类型 - 例如,如果它们有 stdint.h
, , 你可以做:
typedef int32_t my_int32;
很有趣,有 Interlockedexchange - 花费长*的Windows API和 _interlockedexchange MSVC编译器固有的,需要长*。
由于可移植性已被调用,所以我还链接了一个页面 GCC原子质内在.
但是,这一点是很好的:MSVC使用ILP32LLP64 数据模型 对于32位构建和64位构建的LLP64。 Windows确实存在基于GCC的工具链(例如MINGW),并且很可能实现LP64型号 - 导致有趣的!诸如“长”为64位之类的发生,但长期为32。
如果您坚持使用Microsoft编译器,则不必担心。
因此,总而言之:1。通过的价值必须具有“挥发性”的资格。 2.因为您(a)使用32位数量(这是您的要求),并且(b)使用明确的32位互锁API的32位形式 - 它的100%安全可靠地进行血腥的铸件,并可以完成:即将在所有位尺寸的32位值上运行,即使使用不同的数据模型,您的变量也将在所有位尺寸上明确32bits。
演员是安全的,不要无缘无故使事情变得复杂。
汉斯传教士 表达很好:
“原子增量是一个重型平台实施细节。”
这就是为什么实施提供特定类型过载的原因。
atomic_ops
就是这样一个项目。
从理论上讲,每个互锁的函数都可以通过使用全面锁来实现 - 在旋转中,依靠平台细节:-) - 但这是对目标硬件平台上支持的类型和功能的真正性能。