Home  >  Article  >  Backend Development  >  Detailed explanation of .NET synchronization and asynchronous Mutex

Detailed explanation of .NET synchronization and asynchronous Mutex

迷茫
迷茫Original
2017-03-26 16:10:262454browse

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.

1. Abstract base class WaitHandle

[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.

2. Mutex (process synchronization lock)

1. MSDN defines Mutex as the synchronization primitive between processes, that is, the concept of lock.

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

2. Usage of Mutex

  • 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.

    ReleaseMutex(): Release the current Mutex once. Note that this is emphasized once, because the thread that owns the mutex can repeatedly call the WaitOne series of functions without blocking its execution; this and the Monitor's Enter()/Exit() can be called repeatedly after acquiring the object lock. Same. The number of times Mutex is called is saved by the common language runtime (CLR). The count is +1 for each WaitOne() and -1 for each ReleaseMutex(). As long as this count is not 0, other Mutex waiters will consider this Mutex If it is not released, there is no way to obtain the Mutex. In addition, like Monitor.Exit(), only the owner of the Mutex can RleaseMutex(), otherwise an exception will be thrown.
  • If the thread terminates while owning the mutex, we call the mutex abandoned. In MSDN, Microsoft warns that this is a "serious" programming error. This means that after the owner of the mutex obtains ownership, the number of WaitOne() and ReleaseMutex() is unequal, and the caller itself terminates irresponsibly, causing the resource being protected by the mutex to be in an inconsistent state. In fact, this is nothing more than a reminder to remember to use Mutex
  • in the try/finally structure.

3、全局和局部的Mutex

如果在一个应用程序域内使用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访问的安全性控制。

4、用途 

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn