【问题标题】:.net Lock - Two Questions.net 锁定 - 两个问题
【发布时间】:2012-04-26 10:33:54
【问题描述】:

.net 中关于 Lock() 构造的两个问题

首先,我知道如果一个对象被锁定在一个类中,而另一个类试图锁定同一个对象,则会产生死锁。但为什么?我在 MSDN 上读过它,但 MSDN 很少那么清楚。

----编辑问题一---- 还是一头雾水。我有一个产生许多 Threadpool 线程的主线程(UI 线程)。每个子线程在使用数据之前都会锁定数据。每次都能正常工作。

如果我随后尝试从 UI 线程锁定相同的数据以检查我是否应该为边缘情况创建一个新线程,我几乎每次都会创建死锁。

----编辑问题二---- 其次,如果我有一个我锁定的复合对象,那么其中的所有子对象是否也被锁定?短代码演示:

internal sealed class Update
{
    //Three objects instantiated via other external assemblies
    public DataObject One { get; set; }
    public DataObject Two { get; set; }
    public ReplayStatus Status { get; set; }
}

如果我调用 lock(UpdateObject),三个内部对象和所有子对象都被锁定了吗?

所以我应该做这样的事情来防止线程玩弄我的数据对象:

Lock(UpdateObject.One)
{
    Lock(UpdateObject.Two)
    {
        Lock(UpdateObject.Status)
        {
            //Do Stuff
        }
    }
} 

【问题讨论】:

  • Great article on deadlocks,假设这不是不清楚的。
  • 所以后续会是 Lock 可以防止我的所有线程池线程形成竞争条件。我的部分代码很好的解决方案,但不足以解决我的男女同校面临的新问题。我需要使用互斥锁来防止访问来自不同代码段的数据。

标签: c# .net multithreading


【解决方案1】:

首先,我知道如果一个对象被锁定在一个类中,而另一个类尝试锁定同一个对象,则会产生死锁。

没有。如果一个线程锁定了一个对象,而另一个线程尝试锁定该对象,则第二个线程必须等待第一个线程退出锁定。

死锁是另外一回事:

1. thread1 locks instanceA
2. thread2 locks instanceB
3. thread1 attempts to lock instanceB and now must wait on thread2
4. thread2 attempts to lock instanceA and now must wait on thread1

这两个线程不能再执行,因此永远不会释放它们的锁。真是一团糟。

如果我调用 lock(UpdateObject),三个内部对象和所有子对象都被锁定了吗?

不,“锁定”仅在锁定的实例上。注意:锁不会阻止除第二个线程之外的任何东西同时获取该实例上的锁。

【讨论】:

  • 更新了我的问题以反映您的回复
【解决方案2】:

首先,锁的全部意义在于两段代码不能同时获得同一个锁。这是为了协调多个线程使用相同的东西而不相互干扰。如果您在一个对象上有一个锁,那么任何其他试图获得锁的人都会阻塞(等待)直到原始锁被释放(在任何给定时间只有一个线程可以拥有锁)。如果第一个线程从不放弃锁,或者如果两个线程都在等待对方的某些东西并且在每个线程都得到它正在等待的东西之前都不能继续,那么你只会遇到死锁。

其次,如果您在 C# 中 lock 一个对象,那么您实际上并没有在任何语义意义上“锁定”该对象。您正在获取对象上的“锁定”(稍后释放放弃)。该对象纯粹是一个方便的令牌,用于唯一标识您希望获得的锁。所以不,对象上的锁不会在该对象的任何子部分上创建锁。

【讨论】:

  • 更新了我的问题以反映您的回复
  • @Ritz:锁定一个对象不会阻止另一个线程使用它。它只是防止在同一个对象上获得另一个锁。
  • 卡梅伦,我刚收到。我需要一个互斥锁!
  • @Ritz:锁仍然是最简单的方法。您只需确保所有适用于数据的代码都包含在某个对象的锁定中(每个可以修改数据的代码部分的相同对象)。这样,当一个部分在做某事时,如果另一个部分也想做某事,它必须等待,但是一旦第一个部分完成,锁就会被释放,第二个部分然后获得锁并可以做它的事情安全。
  • @Ritz:回复您编辑的评论:锁(在内部使用监视器)提供与互斥锁几乎相同的功能,但速度更快。这可能就是你所需要的。见stackoverflow.com/questions/1164038/monitor-vs-mutex-in-c-sharp
猜你喜欢
  • 1970-01-01
  • 2017-11-05
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多