簡體   English   中英

使用 InterlockedCompareExchange 無鎖

[英]Lockless using InterlockedCompareExchange

我正在嘗試使用聯鎖操作使以下代碼片段無鎖,知道如何翻譯嗎?

if (m_Ref == 0xFFFF)
    m_Ref = 1;
else
{
    if (++m_Ref == 1)
        CallSomething(); //

}

我在想類似的東西

if (InterlockedCompareExchange(&m_Ref, 1, 0xFFFF) != 0xFFFF))
{
    if (InterlockedIncrement(&m_Ref) == 1)
         CallSomething();
}

這有什么問題/種族嗎?

從表面上看,這看起來是正確的,但每次你連續使用兩個互鎖操作時,你都會將自己暴露在ABA 問題中。 在這種情況下,一個線程無法將其從 0xFFFF 更改為 1(ICX 返回!=0xFFFF ),因此它繼續執行if分支並將其遞增。 在運行InterlockedIncrement之前,另一個線程將m_ref更改回 0xFFFF,原始線程遞增 0xFFFF。 根據 m_ref 的類型/語義,效果會很謹慎,但肯定會很糟糕。

您應該對 0xFFF 到 1 和 X 到 X+1 執行一次 ICX 操作,如果丟失 ICX,請始終重試:

volatile <type> m_ref;

<type> ref, newRef, icxref;
do
{
   ref = m_ref;
   newRef = (0xFFFF == ref) ? 1 : ++ref;
   icxref = InterlockedCompareExchange (&m_ref, newRef, ref);
} while (icxref != ref);
if (newRef == 1 && ref != 0xFFFF)
{
   DoSomething ();
}

是的,有一場比賽。 另一個上下文可以在InterlockedCompareExchangeInterlockedIncrement之間做很多事情

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM