This essay is continued: .NET synchronization and asynchronous thread-safe collection (11)
This essay and the next two essays will introduce the last major part of the .NET synchronization and asynchronous series. Block knowledge points: WaitHandle family.
Abstract base class: WaitHandle, three subclasses: EventWaitHandle (Event notification), Mutex (process synchronization lock), Semaphone (semaphore), and two grandchildren: System.Threading.AutoResetEvent, System. Threading.ManualResetEvent are all subclasses of EventWaitHandle.
[ComVisibleAttribute(true)]public abstract class WaitHandle : MarshalByRefObject, IDisposable
Through the above information, we can know that WaitHandle inherits from MarshalByRefObject and implements the IDisposable interface.
You may not be very familiar with MarshalByRefObject, but you will definitely have used many of its subclasses. Let us reveal its true face.
MarshalByRefObject is described in MSND like this:
The application domain is a partition where one or more applications reside in an operating system process. Objects in the same application domain communicate directly. Objects in different application domains can communicate in two ways: by transferring copies of objects across application domain boundaries, or by using proxies to exchange messages. MarshalByRefObject is the base class for objects that communicate across application domain boundaries by exchanging messages using proxies.
You may be more confused after seeing this. Have I used it? Used its subclasses? That's right, its subclasses have been used, and there are many more.
For example, Brush, Image, Pen, Font, etc. in the System.Drawing namespace, and there is also a more familiar Stream under the System.IO namespace.
Extended reading: Utilization MarshalByRefObject Implements AOP.
Seeing this, we only need to know that WaitHandle has the ability to communicate across application domains.
On the other hand, Monitor is usually only used to communicate between threads in the application domain. In fact, Monitor can also provide locking in multiple application domains if the object used for the lock is derived from MarshalByRefObject.
Since Mutex needs to call operating system resources, its execution overhead is much greater than Monitor. Therefore, if you only need to synchronize operations between threads within the application, Monitor/lock should be the first choice
WaitOne() /WaitOne(TimeSpan, Boolean) and several overloads: request ownership, this call will block until the current mutex receives a signal, or until When the optional timeout interval is reached, none of these methods need to provide a lock object as an additional parameter.
You can use the WaitHandle.WaitOne method to request ownership of a mutex. The calling thread is blocked until one of the following occurs:
The mutex signals non-ownership. In this case, the WaitOne method will return true, , mutex ownership of the calling thread, and access to the resource protected by the mutex. After the thread completes accessing resources, the ReleaseMutex method must be called to release the ownership of the mutex.
##Have methods millisecondsTimeout or ## for the timeout interval specified in the call to WaitOne #timeout The parameter has expired. In this case, the WaitOne method will return false, and the thread will not acquire ownership of the mutex at this time.
如果在一个应用程序域内使用Mutex,当然不如直接使用Monitor/lock更为合适,因为前面已经提到Mutex需要更大的开销而执行较慢。不过Mutex毕竟不是Monitor/lock,它生来应用的场景就应该是用于进程间同步的。用于在进程间通讯的Mutex我们称为全局Mutex,而只用于在应用程序域内部通讯的Mutex、我们称为局部Mutex.
全局Mutex和局部Mutex是通过构造函数来构造不同的实例的,让我们来看一下Mutex的构造函数,一共有5个,挑两个具有代表性的看一下吧:
Mutex():用无参数的构造函数得到的Mutex没有任何名称,而进程间无法通过变量的形式共享数据,所以没有名称的Mutex也叫做局部(Local)Mutex。另外,这样创建出的Mutex,创建者对这个实例并没有拥有权,仍然需要调用WaitOne()去请求所有权。
Mutex(Boolean initiallyOwned, String name, out Booldan createdNew, MutexSecurity):第一个bool参数:指示初始化的实例是否拥有互斥体所有权。第二个string类型、为互斥体指定一个名称,如果string为null或者空字符串 则相当于创建一个没有名字的Mutex,当属于局部Mutex. 而有名字的Mutex当属于全局Mutex.第三个bool参数、如果已经初始化了互斥体 返回True, 如果互斥体已经存在则返回False. 最后一个参数用于Mutex访问的安全性控制。
Mutex天生为进程间的同步基元,因此它可以用来控制应用程序的单实例:
/// <summary>/// 单实例运行/// </summary>/// <returns> true 应用程序已启动,false 则没有 </returns>public bool SingleRun(ref System.Threading.Mutex mutex ) { mutex = new System.Threading.Mutex(false, "WINDOWS"); if (!mutex.WaitOne(0, false)) { mutex.Close(); mutex = null; } if (mutex == null) { return true; } return false; }
The above is the detailed content of Detailed explanation of .NET synchronization and asynchronous Mutex. For more information, please follow other related articles on the PHP Chinese website!