我正在尝试在多线程.NET应用程序中的共享变量中设置位标志,但在托管的InterlockedOr类中找不到与 native Interlocked函数的并行项。我想出了下面的代码来执行| =赋值,但是从理论上讲,无限循环使我感到不舒服:

long currentValue;
long updatedValue;

do
{
    // Spin until successful update. Value must be read using Interlocked.Read()
    // to be truly atomic on 32 bit systems (see MSDN).
    currentFlags = Interlocked.Read(ref _currentFlags);
    updatedValue = currentFlags | flag;
} while (currentFlags != Interlocked.CompareExchange(ref _currentFlags, updatedValue, currentFlags));

是否可以仅使用Interlocked类中内置的函数以更安全的方式来实现?如果可能,我想避免涉及显式锁定的解决方案。

最佳答案

让我们假设(这些限制不是基本的,只是为了简化说明)

开头currentFlags

  • 0
  • 我们一步设置最多一个标志
  • 我们不触摸符号位。

  • 请注意,如果一次将k中的1设置为currentFlags,则可以将or替换为+ 1L << k。因此,我们可以使用辅助数组set来记住已设置的位,并在需要时执行Interlocked.Add
    long currentFlags = 0;
    int[] set = new int[sizeof(long) * 8];
    
    ....
    
    int k = ...; // bit to set
    if(Interlocked.Exchange(ref set[k], 1) == 0)
        Interlocked.Add(ref currentFlags, 1L << k);
    

    10-07 22:36