移植 InterlockedExchange,仅使用 GCC 内在函数

Posted

技术标签:

【中文标题】移植 InterlockedExchange,仅使用 GCC 内在函数【英文标题】:Porting InterlockedExchange, using GCC intrinsics only 【发布时间】:2012-01-06 06:47:27 【问题描述】:

Windows API 提供InterlockedExchange,它以原子方式在内存中设置一个值。仅使用 GCC 内部函数,我想创建一个与该函数等效的函数。设置值然后调用内存屏障就足够了(参见下面的代码)?

template <typename T>
T InterlockedExchange(volatile T& _data, T _value)

    const T oldValue = _data;
    _data = _value;
    __sync_synchronize();
    return oldValue;

谢谢。

编辑:建议的 sn-p 不是解决问题的正确方法,因为它显然不是原子的(但是,我不得不试一试至少)。

【问题讨论】:

您将_data 参数声明为引用,但稍后使用指针解引用访问它。 【参考方案1】:

使用 __sync_val_compare_and_swap __sync_lock_test_and_set,而不是 __sync_synchronize

这与 InterlockedExchange 的功能完全相同。

类似这样的东西(未经测试的代码!):

template<typename T> T InterlockedExchange(T& data, T& new_val)

    return __sync_lock_test_and_set(&data, new_val);

编辑: 喂,我看错了,你想要的是 InterlockedExchange,而不是 InterlockedCompareExchange ......所以这是 __sync_lock_test_and_set(这个名字是一个误导性的英特尔名词,但它正是你想要的)。 请参阅页面底部的here。

【讨论】:

注意__sync_lock_test_and_set()只有Acquire语义,所以这仅相当于InterlockedExchangeAcquire()。您需要为完整的内存屏障添加__sync_synchronize();,相当于InterlockedExchange()【参考方案2】:

您提出的示例不等效,因为它不是原子的。执行您的函数的两个竞赛线程都可以检索相同的旧值,其中一个新值“丢失”。

【讨论】:

确实,我一找到解决办法就改:)

以上是关于移植 InterlockedExchange,仅使用 GCC 内在函数的主要内容,如果未能解决你的问题,请参考以下文章

找不到名为“interlockedexchange”的入口点

InterlockedExchange() 类型函数/内在函数的 MSDN 文档不一致?

同步线程 - InterlockedExchange

InterlockedExchange Visual Studio 2010 内在

仅使 QTreeWidgetItem 的一列可编辑

仅使某些查询字段可编辑