1

我有一些代码,我无法正确理解。问题是程序是多线程的,其中有一些代码应该同步,所以我写了这个:

lock (lockObject)
{
   if (!Monitor.TryEnter(lockObject))
     Monitor.Wait(lockObject);

   //do stuff...
   Monitor.PulseAll(lockObject);
}
Monitor.Exit(lockObject);

我遇到的问题是,在某个时间点,所有线程似乎都在睡觉——有人能说出原因吗?该程序一直在无休止地运行,几乎没有消耗cpu,但没有完成任何工作——在跟踪程序时,我发现在某些时候没有线程处于活动状态,但其中很多都在休眠。我知道大部分错误(如果是开发人员 - 总是)位于显示器前面 0.5m 处 - 但我自己无法弄清楚......也许在几分钟内;)

有人可以向我解释一下 - 在此先感谢。

4

3 回答 3

3

我假设第一个 lock 语句是一个错字,你的意思是 lock(lockObject) (小写)。

我认为你在这里对锁有点误解。代码中的 if 块永远不会是真的。原因是 lock(lockObject) 实际上扩展到以下

Monitor.Enter(lockObject);
try {
...
} finally{ 
Monitor.Exit(lockObject);

因此,当您点击 if 块时,您已经拥有锁并且 TryEnter 应该总是成功。

于 2009-03-13T13:22:53.950 回答
1

LockObject和有区别lockObject吗?不清楚...

然而!如果它们是不同的对象,那么首先:您不能使用您没有Wait的锁......并且TryEnter只有在您指定超时时才会返回 false。这段代码到底想做什么?

没有更多上下文,并不完全清楚PulseAllandWait的目的是什么。例如,在这里它们用于在队列太满时阻塞(Wait),或者在空间可用时释放它(PulseAll)等。如果没有线程之间的完全交互,很难调试线程代码。

听起来您可能只需要:

lock (lockObject)
{
    // do stuff
}

我可以看到两个直接的问题;首先,你总是释放你使用的锁(即异常)并不明显。尝试只使用lock-Enter/Exit它会得到它的权利。

第二; 如果所有线程都调用Wait......谁来唤醒它们?他们还在等什么?如前所述:是的,他们都会无限期地睡觉。

于 2009-03-13T13:23:36.990 回答
1

这是一个奇怪的设置。“LockObject”和“lockObject”一样吗?或者这是一个错字?如果它们相同,那么您的设置是多余的,因为不需要在您已经锁定的东西上调用 Monitor.TryEnter。如果“LockObject”是一个不同的对象,那么为什么不将 Monitor.Exit 移到 lock 语句中呢?

于 2009-03-13T13:25:55.097 回答