首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么lock比Monitor.TryEnter慢得多?

为什么lock比Monitor.TryEnter慢得多?
EN

Stack Overflow用户
提问于 2010-03-10 20:26:57
回答 3查看 17.7K关注 0票数 22

结果

锁定: 85.3微秒

Monitor.TryEnter: 11.0微秒

锁不是扩展成了相同的代码吗?

编辑: 1000次迭代的结果:锁定: 103.3微秒Monitor.TryEnter: 20.2微秒

下面的代码。谢谢

代码语言:javascript
复制
    [Test]
    public void Lock_Performance_Test()
    {
        const int lockIterations = 100;

        Stopwatch csLock = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; )
        {
            lock (object1)
            {
                i++;
            }
        }
        csLock.Stop();

        Stopwatch csMonitor = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; )
        {
            if (Monitor.TryEnter(object1, TimeSpan.FromSeconds(10)))
            {
                try
                {
                    i++;
                }
                finally
                {
                    Monitor.Exit(object1);
                }
            }
        }
        csMonitor.Stop();

        Console.WriteLine("Lock: {0:f1} microseconds", csLock.Elapsed.Ticks / 10M);
        Console.WriteLine("Monitor.TryEnter: {0:f1} microseconds", csMonitor.Elapsed.Ticks / 10M);;
    }
EN

回答 3

Stack Overflow用户

发布于 2010-03-10 20:29:32

可能是因为lock是Monitor.Enter,而不是Monitor.TryEnter?

票数 3
EN

Stack Overflow用户

发布于 2010-03-10 20:45:07

您可以使用.NET反射器来检查生成的IL。lock关键字使用Monitor.Enter而不是Monitor.TryEnter -这是您问题的简短答案。下面是您的代码在反汇编并转换回C#时的样子:

代码语言:javascript
复制
public void Lock_Performance_Test()
{
    Stopwatch csLock = Stopwatch.StartNew();
    int i = 0;
    while (i < 100)
    {
        object CS$2$0000;
        bool <>s__LockTaken0 = false;
        try
        {
            Monitor.Enter(CS$2$0000 = this.object1, ref <>s__LockTaken0);
            i++;
        }
        finally
        {
            if (<>s__LockTaken0)
            {
                Monitor.Exit(CS$2$0000);
            }
        }
    }
    csLock.Stop();
    Stopwatch csMonitor = Stopwatch.StartNew();
    i = 0;
    while (i < 100)
    {
        if (Monitor.TryEnter(this.object1, TimeSpan.FromSeconds(10.0)))
        {
            try
            {
                i++;
            }
            finally
            {
                Monitor.Exit(this.object1);
            }
        }
    }
    csMonitor.Stop();
    Console.WriteLine("Lock: {0:f1} microseconds", csLock.Elapsed.Ticks / 10M);
    Console.WriteLine("Monitor.TryEnter: {0:f1} microseconds", csMonitor.Elapsed.Ticks / 10M);
}
票数 3
EN

Stack Overflow用户

发布于 2016-04-09 02:12:23

如果你需要速度,那么根据我的经验,SpinLock是一个更好的选择。

代码语言:javascript
复制
public class DisposableSpinLock : IDisposable {
    private SpinLock mylock;
    private bool isLocked;

    public DisposableSpinLock( SpinLock thelock ) {
        this.mylock = thelock;
        mylock.Enter( ref isLocked );
    }

    public DisposableSpinLock(  SpinLock thelock, bool tryLock) {
        this.mylock = thelock;
        if( tryLock ) {
            mylock.TryEnter( ref isLocked );
        } else {
            mylock.Enter( ref isLocked );
        }
    }

    public bool IsLocked { get { return isLocked; } }

    public void Dispose() {
        Dispose( true );
        GC.SuppressFinalize( this );
    }

    protected virtual void Dispose( bool disposing ) {
        if( disposing ) {
            if( isLocked ) {
                mylock.Exit();
            }
        }
    }
}

是在中止和异常情况下让事情“自动”工作的一种非常有用的方法。

您可以只创建一个锁而不是“SpinLock”对象,然后使用:

代码语言:javascript
复制
using( new DisposableSpinLock( myLock ) ) {
     // Under lock and key...
}

这允许您获得lock()提供的相同单行代码,同时还处理所需的try {} finally{}行为,并对清理对象所发生的事情有更多的控制。

我还支持"try“用例,它将使用内部带有额外if语句的代码块来编写:

代码语言:javascript
复制
using( theLock = new DisposableSpinLock( myLock, true ) ) {
    if( theLock.IsLocked ) {
        // Under Lock and Key
    }
}

对于高度争用的锁,SpinLock并不是CPU友好的,因为在这种情况下会增加SpinLock的CPU使用率,但对于那些几乎同步的锁,并且只需要偶尔锁定外部引用或偶尔访问第二个线程,这是一个很大的胜利。

是的,这并不华丽,但对我来说,SpinLocks让我为轻度争用的锁提供的所有东西都更有性能。

http://www.adammil.net/blog/v111_Creating_High-Performance_Locks_and_Lock-free_Code_for_NET_.html是一个很好的自旋锁和整体锁定的例子。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2416793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档