C# 监视器。请稍候,如果是?
目前,我正在学习多线程考试。我读书。我有一个关于监视器使用的问题-为什么这里使用循环来代替ifC# 监视器。请稍候,如果是?,c#,multithreading,monitor,C#,Multithreading,Monitor,目前,我正在学习多线程考试。我读书。我有一个关于监视器使用的问题-为什么这里使用循环来代替if lock (_locker) { while (!_go) //why while and not if? Monitor.Wait (_locker); // _lock is released // lock is regained ... } 我认为,一个if就足够了 恐怕我不完全理解这篇文章 //编辑 示例代码: class SimpleWaitPulse { st
lock (_locker)
{
while (!_go) //why while and not if?
Monitor.Wait (_locker); // _lock is released
// lock is regained
...
}
我认为,一个if就足够了
恐怕我不完全理解这篇文章
//编辑
示例代码:
class SimpleWaitPulse
{
static readonly object _locker = new object();
static bool _go;
static void Main()
{ // The new thread will block
new Thread (Work).Start(); // because _go==false.
Console.ReadLine(); // Wait for user to hit Enter
lock (_locker) // Let's now wake up the thread by
{ // setting _go=true and pulsing.
_go = true;
Monitor.Pulse (_locker);
}
}
static void Work()
{
lock (_locker)
while (!_go)
Monitor.Wait (_locker); // Lock is released while we’re waiting
Console.WriteLine ("Woken!!!");
}
}
这要视情况而定。在这种情况下,代码只是等待
\u go
变为true
每次\u locker
被触发时,它都会检查\u go
是否已设置为true。如果\u go
仍然为false,它将等待下一个脉冲
如果使用If而不是一段时间,它将只等待一次(如果\u go
已经为true,则根本不会等待),然后在脉冲后继续,而不管\u go
的新状态如何
因此,如何使用Monitor.Wait()完全取决于您的具体需要 这取决于具体情况。但首先,我们需要澄清监视器是如何工作的。当一个线程继续通过Monitor.Pulse()向一个线程发送信号时,通常无法保证发出信号的线程下一步是否会实际运行。这意味着其他线程可以在发出信号的线程之前运行,并更改发出信号的线程可以继续运行的条件。这意味着发出信号的线程在被唤醒(即while循环)后仍需要检查是否安全才能继续。但是,某些罕见的同步问题允许您假设,一旦一个线程被信号唤醒(即Monitor.Pulse()),就没有其他线程能够更改安全继续的条件(即if条件)。我写了一篇文章,这篇文章可能会有所帮助: 现在发生的事情远不止是显而易见的 我有一个关于监视器使用的问题-为什么这里使用循环 if的位置
lock (_locker)
{
while (!_go) //why while and not if?
Monitor.Wait (_locker); // _lock is released
// lock is regained
...
}
使用Pulse
和Wait
时有一条众所周知的规则,即当有疑问时,宁愿使用而不是if
。显然,在这种情况下两种方法都可以,但在几乎所有其他情况下都需要,而是必需的。事实上,使用while
循环会产生错误结果的情况很少(如果有的话)。这是这一一般规则的基础。作者使用了while
循环,因为他试图坚持久经考验的真实模式。他甚至在同一篇文章中提供了模板。这是:
lock (_locker)
while ( <blocking-condition> )
Monitor.Wait (_locker);
锁(\u锁柜)
而()
监视器。等待(_locker);
使用监视器写入正确代码的最简单方法是假设系统将其视为“建议”,并假设系统可以在任何时候获取锁时任意唤醒任何等待线程,而不考虑是否调用了脉冲。当然,系统通常不会这样做,但是如果程序正确地使用了Wait
和Pulse
,那么Wait
调用会无缘无故地提前退出,不会影响其正确性。本质上,我们应该把等待看作是告诉系统“如果”只检查一次“那么,除非或直到其他人调用脉冲,否则在这里继续执行将是浪费时间”的一种方式。“while”循环将继续检查。如果你不等待。等待。你好,谢谢你的解释。但我认为Monitor.Wait操作只会执行一次。它将等待脉冲信号。所以我暂时看不出有什么理由:-(这取决于程序的其余部分,例如\u go
的确切含义,以及您何时设置它。您好,斯维克-谢谢您的回答。我添加了示例。pro,这实际上取决于您希望等待事件发生的次数。通常,在锁定后内存中会有某种类型的修改,如果您不想这样做的话o“观察”该修改一次,然后您可以使用if(例如,您发送一条消息并等待一个响应)。如果您想持续“观察”该修改,则在while循环中进行(即,您正在监视消息流中的大量消息)。