Sur*_*esh 5 c++ multithreading synchronization interlocked
我试图使用互锁操作使代码片段无锁,任何想法如何翻译?
if (m_Ref == 0xFFFF)
m_Ref = 1;
else
{
if (++m_Ref == 1)
CallSomething(); //
}
Run Code Online (Sandbox Code Playgroud)
我在想类似的东西
if (InterlockedCompareExchange(&m_Ref, 1, 0xFFFF) != 0xFFFF))
{
if (InterlockedIncrement(&m_Ref) == 1)
CallSomething();
}
Run Code Online (Sandbox Code Playgroud)
这有什么问题/竞争吗?
这看起来很正确,但是每次你连续使用两个互锁操作时,你都会暴露自己的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 ();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9660 次 |
| 最近记录: |