use*_*834 159 c# multithreading synchronization mutex locking
有人可以解释之间的区别:
我只是想不出来.在我看来前两个是一样的?
Gis*_*shu 133
好问题.我可能错了..让我试试..我的原始答案的修订版#2 ......稍微有点理解.谢谢你让我读:)
锁(OBJ)
显示器
使用锁或监视器对于防止同时执行线程敏感的代码块很有用,但这些构造不允许一个线程将事件传递给另一个.这需要同步事件,这些事件是具有信号和未信号两种状态之一的对象,可用于激活和挂起线程.Mutex,Semaphores是操作系统级别的概念.例如,使用命名的互斥锁,您可以跨多个(托管)的exes进行同步(确保只有一个应用程序实例在计算机上运行.)
互斥:
信号量(伤害了我的大脑).
Mar*_*ell 30
重新"使用其他.Net同步类" - 您应该了解的其他一些:
在CCR/TPL(Parallel Extensions CTP)中还有更多(低开销)锁定结构- 但IIRC,这些将在.NET 4.0中提供
aru*_*rul 15
正如ECMA中所述,正如您可以从Reflected方法中观察到的那样,lock语句基本上等同于
object obj = x;
System.Threading.Monitor.Enter(obj);
try {
…
}
finally {
System.Threading.Monitor.Exit(obj);
}
Run Code Online (Sandbox Code Playgroud)
从前面提到的例子中我们看到监视器可以锁定对象.
当您需要进程间同步时,Mutexe非常有用,因为它们可以锁定字符串标识符.不同进程可以使用相同的字符串标识符来获取锁.
信号量就像类固醇上的互斥体一样,它们通过提供最大数量的并发访问来实现并发访问.达到限制后,信号量开始阻止对资源的任何进一步访问,直到其中一个调用者释放信号量.
tum*_*tum 13
我在DotGNU中为线程做了类和CLR支持,我有一些想法......
除非您需要跨进程锁定,否则应始终避免使用互斥锁和信号量..NET中的这些类是围绕Win32 Mutex和Semaphores的包装器,并且相当重(它们需要上下文切换到内核,这是昂贵的 - 特别是如果你的锁没有争用).
正如其他人所提到的,C#lock语句是Monitor.Enter和Monitor.Exit的编译魔术(存在于try/finally中).
监视器有一个简单但功能强大的信号/等待机制,Mutexes没有通过Monitor.Pulse/Monitor.Wait方法.Win32等价物将是通过CreateEvent的事件对象,它实际上也作为WaitHandles存在于.NET中.Pulse/Wait模型类似于Unix的pthread_signal和pthread_wait,但速度更快,因为在非竞争情况下它们可以完全是用户模式操作.
Monitor.Pulse/Wait很简单易用.在一个线程中,我们锁定一个对象,检查一个标志/状态/属性,如果它不是我们所期望的,请调用Monitor.Wait,它将释放锁并等待直到发送一个脉冲.等待返回时,我们循环返回并再次检查flag/state/property.在另一个线程中,每当我们更改flag/state/property然后调用PulseAll来唤醒任何侦听线程时,我们都会锁定对象.
通常我们希望我们的类是线程安全的,所以我们在我们的代码中放置了锁.但是,通常情况是我们的类只会被一个线程使用.这意味着锁会不必要地减慢我们的代码......这就是CLR中的巧妙优化可以帮助提高性能的地方.
我不确定微软的锁实现,但在DotGNU和Mono中,锁状态标志存储在每个对象的标头中..NET(和Java)中的每个对象都可以成为一个锁,因此每个对象都需要在其标题中支持它.在DotGNU实现中,有一个标志允许您为每个用作锁的对象使用全局哈希表 - 这有利于消除每个对象的4字节开销.这对于内存来说并不是很好(特别是对于没有高度线程化的嵌入式系统)但是性能受到打击.
Mono和DotGNU都有效地使用互斥锁执行锁定/等待,但使用自旋锁式比较和交换操作,除非确实需要,否则无需实际执行硬锁:
您可以在此处查看如何实现监视器的示例:
http://cvs.savannah.gnu.org/viewvc/dotgnu-pnet/pnet/engine/lib_monitor.c?revision=1.7&view=markup
锁定在您使用字符串ID标识的任何共享互斥锁上的另一个警告是它将默认为"本地"互斥锁,并且不会在终端服务器环境中的会话之间共享.
使用"Global \"作为字符串标识符的前缀,以确保正确控制对共享系统资源的访问.在我意识到这一点之前,我刚刚遇到了一大堆问题,这些问题与SYSTEM帐户下运行的服务同步通信.
如果可以的话,我会尽量避免"锁定()","互斥"和"监视"......
在.NET 4中查看新的命名空间System.Collections.Concurrent
它有一些很好的线程安全的集合类
http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx
ConcurrentDictionary摇滚!我不再手动锁定了!
归档时间: |
|
查看次数: |
33962 次 |
最近记录: |