【问题标题】:InterlockedExchange (or similar atomic operation) within a Critical Section?关键部分中的 InterlockedExchange(或类似的原子操作)?
【发布时间】:2012-02-16 09:43:41
【问题描述】:

我看到一些重复的代码(准确地说是方法),它们进入临界区,然后使用 InterlockedExchange...这有意义吗,因为我认为这个操作实际上是原子的,不需要这种同步?

{ 
  EnterCricSectionLock lock (somelock);
  InterlockedExchange(&somelong, static_cast<long>(newlongVal));
}

基本上就是这样……

【问题讨论】:

    标签: c++ synchronization critical-section


    【解决方案1】:

    正常的交换通常不是原子的。但是,如果所有其他用途都受到同一个互斥锁的保护,则可以在拥有互斥锁的同时执行此操作。如果所有其他用途都是原子的,也可以使用原子交换。我能想到在拥有互斥锁的同时进行原子交换的唯一合乎逻辑的原因是,并非所有对这个值的使用都受到互斥锁保护。

    【讨论】:

    • “不是”原子的吗? MSDN:“将 32 位变量设置为指定值作为原子操作。”当然,你所说的“所有其他用户”是必须的:他们都必须使用联锁功能。
    • 原子交换当然是原子的。我的意思是正常的交换通常不是原子的。
    • 好的,很抱歉造成误解(但由于这个问题特别针对InterlockedExchange,我对此并不感到难过;-)
    • 有点不清楚(早上太早了)。我已经编辑过,希望现在更清楚。
    【解决方案2】:

    单个原子操作不需要 CS,但它可以充当栅栏以在锁保持全局可见时进行任何更改(IIRC,显式栅栏适用于 SSE2+,但互锁操作不需要 SSE 在all),但是它需要任何全局存储之后。

    这可能是有意义的,因为 CS 用于锁定对其他事物的访问,因此交换的全局不是锁定的一部分。

    【讨论】:

    • 根据MSDN 它“生成一个完整的内存屏障(栅栏)”。所以我想除了联锁操作之外,不需要使用 CS。 +1 说明它可能是 CS 保护的“更大”不变量的一部分。
    • @Christian.K:我的措辞有点糟糕,让它更清楚一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    相关资源
    最近更新 更多