Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在Albahari';的LockFreeUpdate示例中需要SpinWait;s";C中的螺纹;_C#_Multithreading_Lock Free_Optimistic Concurrency_Spinwait - Fatal编程技术网

C# 为什么在Albahari';的LockFreeUpdate示例中需要SpinWait;s";C中的螺纹;

C# 为什么在Albahari';的LockFreeUpdate示例中需要SpinWait;s";C中的螺纹;,c#,multithreading,lock-free,optimistic-concurrency,spinwait,C#,Multithreading,Lock Free,Optimistic Concurrency,Spinwait,我正在使用无锁乐观更新方法进行小型的Ref抽象(应该使用不可变的T数据结构,特别是不可变的树)。 它基于Albahari的“C#中的线程化”LockFreeUpdate方法,在第节: static void LockFreeUpdate<T> (ref T field, Func <T, T> updateFunction) where T : class { var spinWait = new SpinWait(); while (true) {

我正在使用无锁乐观更新方法进行小型的
Ref
抽象(应该使用不可变的
T
数据结构,特别是不可变的树)。 它基于Albahari的“C#中的线程化”
LockFreeUpdate
方法,在第节:

static void LockFreeUpdate<T> (ref T field, Func <T, T> updateFunction) where T : class
{
  var spinWait = new SpinWait();
  while (true)
  {
    T snapshot1 = field;
    T calc = updateFunction (snapshot1);
    T snapshot2 = Interlocked.CompareExchange (ref field, calc, snapshot1);
    if (snapshot1 == snapshot2) return;
    spinWait.SpinOnce();
  }
}

谷歌的“英特尔暂停指令”是合适的。问题不在于SpinWait幕后机制,而在于它在我的具体情况下的必要性。这是不可能的,使用并发分析器。你的意思是吗?@dadhi只是一个想法:如果出现多个冲突,可能会延迟线程?
public sealed class Ref<T> where T : class
{
    public T Value { get { return _value; } }

    public Ref(T initialValue = default(T))
    {
        _value = initialValue;
    }

    public T Update(Func<T, T> update)
    {
        var retryCount = 0;
        while (true)
        {
            var oldValue = _value;
            var newValue = update(oldValue);
            if (Interlocked.CompareExchange(ref _value, newValue, oldValue) == oldValue)
                return oldValue;
            if (++retryCount > RETRY_COUNT_UNTIL_THROW)
                throw new InvalidOperationException(ERROR_EXCEEDED_RETRY_COUNT);
        }
    }

    private T _value;

    private const int RETRY_COUNT_UNTIL_THROW = 10;
    private static readonly string ERROR_EXCEEDED_RETRY_COUNT =
        "Ref retried to Update for " + RETRY_COUNT_UNTIL_THROW + " times But there is always someone else intervened.";
}