我正在尝试在多线程.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);