有人能解释一下以下几种方式的区别吗:
lock (someobject) {}
- 使用 Mutex
- 使用 Semaphore
- 使用 Monitor
- 使用其他 .Net 同步类
我就是搞不懂,前两种方式好像是一样的?
有人能解释一下以下几种方式的区别吗:
lock (someobject) {}
我就是搞不懂,前两种方式好像是一样的?
这是一个很好的问题。我可能会错,让我试试。我的原始答案第二次修订。现在我更加理解了。感谢你让我读一下 :)
lock(obj)
监视器
使用锁或监视器可用于防止线程敏感代码的同时执行,但这些结构不允许一个线程向另一个线程通信事件。这需要同步事件,即具有两个状态(已标记和未标记)的对象,可用于激活和挂起线程。 Mutex、Semaphores是操作系统级别的概念。例如,使用命名互斥体可以在多个(托管的)exe之间进行同步(确保应用程序在机器上只运行一个实例)。
互斥体:
信号量(伤脑筋)。
使用Semaphore类来控制资源池的访问。线程通过调用继承自WaitHandle类的WaitOne方法进入信号量,并通过调用Release方法释放信号量。 每当线程进入信号量时,计数器会递减,释放信号量时计数器会递增。当计数器为零时,后续请求会阻塞,直到其他线程释放信号量。当所有线程均已释放信号量时,计数器达到创建信号量时指定的最大值。 一个线程可以多次进入信号量,Semaphore类不在WaitOne或Release上执行线程标识验证,程序员需确保不会出错。 信号量分为两种类型:本地信号量和命名系统信号量。如果使用接受名称参数的构造函数创建Semaphore对象,则它与该名称的操作系统信号量相关联。命名系统信号量在整个操作系统中可见,并可用于同步进程的活动。 本地信号量仅存在于进程内。任何具有对本地Semaphore对象的引用的线程都可以使用它。每个Semaphore对象都是单独的本地信号量。关于"使用其他 .Net 同步类",以下是你应该了解的一些其他同步类:
CCR/TPL(Parallel Extensions CTP)中还有更多(低开销)的锁定结构 - 但我记得这些将在 .NET 4.0 中提供。
正如ECMA所述,并且正如您可以从反射方法中观察到的那样,lock语句基本上等效于
object obj = x;
System.Threading.Monitor.Enter(obj);
try {
…
}
finally {
System.Threading.Monitor.Exit(obj);
}
从上面的例子中,我们可以看到监视器可以锁定对象。
当需要进程间同步时,互斥量非常有用,因为它们可以锁定字符串标识符。不同的进程可以使用相同的字符串标识符来获取锁。
信号量就像是被强化了的互斥量,它们允许并发访问,提供一个最大并发访问计数。一旦达到限制,信号量将开始阻塞任何对资源的进一步访问,直到其中一个调用者释放信号量。
http://cvs.savannah.gnu.org/viewvc/dotgnu-pnet/pnet/engine/lib_monitor.c?revision=1.7&view=markup
如果您要对任何使用字符串ID标识的共享Mutex进行锁定,请注意它将默认为“Local \”mutex,并且在终端服务器环境中不会共享。
请在您的字符串标识符前加上“Global \”,以确保正确控制对共享系统资源的访问。在我意识到这一点之前,我遇到了大量与在SYSTEM帐户下运行的服务同步通信的问题。
http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx
ConcurrentDictionary非常棒!我不再需要手动锁定了!
System.Collections.Concurrent
类-它们不支持与多个集合的事务,并且还使用阻塞同步。Objc/Swift
世界)的串行队列-一种非常轻量级的、不阻塞的同步工具,它使用线程池,并带有测试。