监控VS的WaitHandle基于线程同步 [英] Monitor vs WaitHandle based thread sync

查看:124
本文介绍了监控VS的WaitHandle基于线程同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是IM pression下,阅读后这篇文章,最好是使用监视器/锁的线程同步,因为它不使用本地资源

I was under the impression, after reading this article that it is better to use Monitor/Lock for thread synchronisation as it does not use native resources

具体报价(从文章的第5页):

Specific quote (from page 5 of the article):

Monitor.Wait / Pulse是不是在等待着什么在一个线程中发生的,并告诉该线程,它在另一个是发生的唯一方法。 Win32的程序员一直在使用各种不同机制很长一段时间,而这些是由的AutoResetEvent,ManualResetEvent的互斥和课程,所有这些都从WaitHandle的派生暴露出来。所有这些类是System.Threading命名空间。 (Win32的信号机制没有一个托管的包装在.NET 1.1,它是在.NET 2.0 present,但如果您需要在此之前使用它,你既可以自己使用P / Invoke把它包起来,或写信给你自己的计数信号类)。

Monitor.Wait/Pulse isn't the only way of waiting for something to happen in one thread and telling that thread that it's happened in another. Win32 programmers have been using various other mechanisms for a long time, and these are exposed by the AutoResetEvent, ManualResetEvent and Mutex classes, all of which derive from WaitHandle. All of these classes are in the System.Threading namespace. (The Win32 Semaphore mechanism does not have a managed wrapper in .NET 1.1. It's present in .NET 2.0, but if you need to use it before then, you could either wrap it yourself using P/Invoke, or write your own counting semaphore class.)

有些人可能会惊讶地得知,使用这些类可以比使用各种监视器方法显著慢。我相信这是因为要走出去管理code进入本地Win32中的使用的东西显示器提供完全托管视图相比又是昂贵的来电和背部。一位读者还解释说,监控器在用户模式下实现的,而使用等待句柄需要切换到内核模式,这是相当昂贵的。

Some people may be surprised to learn that using these classes can be significantly slower than using the various Monitor methods. I believe this is because going "out" of managed code into native Win32 calls and back "in" again is expensive compared with the entirely managed view of things which Monitor provides. A reader has also explained that monitors are implemented in user mode, whereas using wait handles require switching into kernel mode, which is fairly expensive.

但由于SO发现并阅读几个问题/答案在这里我开始怀疑我的时候使用的理解。似乎很多人推荐的情况下,一个Monitor.Wait /脉冲会做使用自动/ ManualResetEvent的。当基于WaitHandle的同步应在监视器被用来给我任何人都可以解释一下吗?

But since discovering SO and reading a few of the questions/answers here I have started to doubt my understanding of when to use each. It seems that many people recommend using Auto/ManualResetEvent in the cases where a Monitor.Wait/Pulse would do. Can anyone explain to me when WaitHandle based sync should be used over Monitor?

感谢

推荐答案

Monitor.Pulse / A问题等待是信号可能会丢失。

例如:

var signal = new ManualResetEvent(false);

// Thread 1
signal.WaitOne();

// Thread 2
signal.Set();

这会一直工作无论在哪个在不同的线程两个语句。这也是一个非常干净的抽象和前presses很清楚你的意图。

This will always work no matter in which the two statements in the different threads are executed. It's also a very clean abstraction and expresses very clearly your intent.

现在有使用显示器看看相同的例子:

Now have a look at the same example using a monitor:

var signal = new object();

// Thread 1
lock (signal)
{
    Monitor.Wait(signal);
}

// Thread 2
lock (signal)
{
    Monitor.Pulse(signal);
}

下面的信号(脉冲)会迷失如果脉冲执行等待

Here the signal (Pulse) will get lost if Pulse is executed before Wait.

要解决这个问题,你需要的东西是这样的:

To fix this problem, you need something like this:

var signal = new object();
var signalSet = false;

// Thread 1
lock (signal)
{
    while (!signalSet)
    {
        Monitor.Wait(signal);
    }
}

// Thread 2
lock (signal)
{
    signalSet = true;
    Monitor.Pulse(signal);
}

这工作,可能是更高性能和轻便,但少可读性。而且它是在哪里被称为并发头痛的开始。

This works and is probably even more performant and lightweight, but is less readable. And it's where the headache called concurrency starts.


  • 这是否code真的管用吗?

  • 在每一个角落的情况下?

  • 有超过两个线程?的(提示:事实并非如此)

  • 你怎么单元测试?

坚实,可靠的,可读的抽象往往比原始性能更好。

此外,WaitHandles提供一些不错的东西一样等待句柄来进行设置等方面与显示器实现这使得头痛更糟......

Additionally, WaitHandles provide some nice stuff like waiting for a set of handles to be set, etc. Implementing this with monitors makes the headache even worse...


经验法则:


  • 使用的显示器锁定),以确保对共享资源的独占访问

  • 使用的 WaitHandles (手动/的AutoResetEvent /信号灯)发送线程间的信号

  • Use Monitors (lock) to ensure exclusive access to a shared resource
  • Use WaitHandles (Manual/AutoResetEvent/Semaphore) to send signals between threads

这篇关于监控VS的WaitHandle基于线程同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆