首页 > 解决方案 > 错误地使用 InterlockedCompareExchange 以原子方式复制值?

问题描述

我不能在这里使用 C++11 原子

我怀疑我使用InterlockedCompareExchange()'原子地' 读取变量。

我在这里问了一个关于这个的问题,但我在那里做的事情有所不同。“exchange”和“comperand”参数(第 2 个和第 3 个)是“硬编码”值,即不是从变量中读取的。

请考虑这一点:

    // Copy the connect time
    DWORD dwConnectTime = InterlockedCompareExchange(&msgInfo.m_dwConnectTime, 
                            msgInfo.m_dwConnectTime, 
                            msgInfo.m_dwConnectTime);

这旨在将 的值msgInfo.m_dwConnectTime与 的当前值交换msgInfo.m_dwConnectTime,前提是 的当前msgInfo.m_dwConnectTime值为msgInfo.m_dwConnectTimemsgInfo.m_dwConnectTime然后返回之前的值,这是我依赖于“复制”值的

我刚刚意识到msgInfo.m_dwConnectTime第二个和第三个参数本身的读取并不保证是原子的。因此,这段代码是否不正确,因此我需要使用锁定原语来复制msgInfo.m_dwConnectTime

标签: cmultithreadingwinapi

解决方案


根据评论以及您之前问题的链接,这个问题的动机是您希望避免撕裂。读取和写入对齐的数据是原子的。您正试图防止撕裂,但当数据对齐时,撕裂是不可能的。并且可以合理地假设您的数据是对齐的,因为这是InterlockedCompareExchange所有InterlockedXXX功能的要求。

因此,您要问的问题是不合逻辑的。它基于一个错误的前提,即对齐的数据可能会发生撕裂。

因此,您不需要调用InterlockedCompareExchange或任何其他InterlockedXXX函数来避免撕裂,因为只有在数据未对齐时才能进行撕裂。


推荐阅读