繁体   English   中英

C# 空锁块是否被“优化”掉了?

[英]C# Does an empty lock block get “optimized” away?

我找不到有关 C# 编译器或 JIT 是否会删除内部没有代码的锁定语句的任何信息。 这会始终生成并执行Monitor.EnterMonitor.Exit调用吗?

lock(lockObj) { }

我正在尝试做的一个(大大简化的)版本(是的,我知道在锁中调用回调是不好的):

public class ExecutionSource
{
    private List<Action<object>> _callbacks = new List<Action<object>>();
    private object _value;

    public void AddListener(Action<object> listener)
    {
        object temp = _value;
        if (temp != null)
        {
            listener(temp);
            return;
        }
        lock (_callbacks)
        {
            temp = _value;
            if (temp != null)
            {
                listener(temp);
            }
            else
            {
                _callbacks.Add(listener);
            }
        }
    }

    public void Execute(object value)
    {
        if (value == null) throw new InvalidOperationException("value must be non-null");
        if (Interlocked.CompareExchange(ref _value, value, null) != null)
        {
            throw new InvalidOperationException("Can only execute once.");
        }
        lock (_callbacks) { } // Wait for a listener that is currently being added on another thread. No need to lock the entire loop.
        foreach (var callback in _callbacks)
        {
            callback(value);
        }
        _callbacks.Clear();
    }
}

不,他们没有。 CLI 不能假设没有其他线程已经锁定了 object。

如果任何其他线程(或您当前的代码)尝试使用非零线程锁定Monitor.Enter/Exit ,如果需要,它将 go 进入旋转等待或提升到基于 kernel 的事件。

对于它的价值,因为您不关心重新排序,并且根据您的用例是什么,可能有其他同步原语可能更适合您的特定用例。 像重置事件等。

根据sharplib ,我们可以看到编译器不会删除空锁块。 此外,我无法想象我们如何在真正的多线程环境中在编译时对其进行优化,并确保我们不会破坏任何东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM