如果有:

__int32 some_var = 0;

什么是最好的(如果有)打电话的方法 InterlockedExchange, InterlockedIncrement 以及其他需要的互锁功能 LONG* 为了 some_var ?

因为有保证 LONG 在任何窗户上都是32位,可能只是安全地通过 (long*) some_var. 。但是,在我看来,这很丑陋,我找不到确认它是安全的。

注意,我无法将类型更改为 long 因为它不是便携式的。我完全需要32位类型。

更新: 提供便携式原子操作的图书馆的一些研究表明,没有人对铸造感到困惑。一些例子:

Apache便携式运行时(APR):

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
}

atomic_ops:

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 就是这样一个项目。

从理论上讲,每个互锁的函数都可以通过使用全面锁来实现 - 在旋转中,依靠平台细节:-) - 但这是对目标硬件平台上支持的类型和功能的真正性能。

在这方面正在进行一些标准化,请参阅例如回答的类似问题 这里这里 也是。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top