【发布时间】:2018-10-11 14:12:31
【问题描述】:
我不能在这里使用 C++11 原子
我对使用InterlockedCompareExchange() 来“原子地”读取变量存有疑问。
我问了一个关于这个here 的问题,但我在那里做的事情不同。 “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_dwConnectTime。然后返回之前的 msgInfo.m_dwConnectTime 值,这是我用来“复制”该值的依据。
我刚刚意识到msgInfo.m_dwConnectTime 的第二个和第三个参数本身的读取并不能保证是原子的。因此,这段代码是否不正确,因此我需要使用锁定原语来复制msgInfo.m_dwConnectTime?
【问题讨论】:
-
如果变量对齐,读取是原子的。并且变量必须对齐才能使用
InterlockedCompareExchange。因此,链接问题的公认答案完全是虚假的。您似乎对实际上并不复杂的问题越来越困惑。 -
如果你只想使用联锁函数读取一个值,你可以改用
InterlockedExchangeAdd(),例如:DWORD dwConnectTime = InterlockedExchangeAdd(&msgInfo.m_dwConnectTime, 0);这将返回m_dwConnectTime的“上一个”值,然后将它增加0 , IOW 返回其“当前”值 -
@RemyLebeau 这样做毫无意义。直接读取值即可。对齐访问是原子的。
-
如果你想读取和更改,说
x = x + 1这里需要联锁操作。仅用于读取值(寄存器大小,对齐) - 不需要锁定。阅读后的价值可以随时更改,但这已经是另一个问题了
标签: c multithreading winapi