Mutex.ReleaseMutex Method
Releases the Mutex once.
Assembly: mscorlib (in mscorlib.dll)
| Exception | Condition |
|---|---|
| ApplicationException |
The calling thread does not own the mutex. |
A thread that owns a mutex can specify the same mutex in repeated wait function calls without blocking its execution. The number of calls is kept by the common language runtime. The thread must call ReleaseMutex the same number of times to release ownership of the mutex.
If a thread terminates while owning a mutex, the mutex is said to be abandoned. The state of the mutex is set to signaled and the next waiting thread gets ownership. If no one owns the mutex, the state of the mutex is signaled. Beginning in version 2.0 of the .NET Framework, an AbandonedMutexException is thrown in the next thread that acquires the mutex. Prior to version 2.0 of the .NET Framework, no exception was thrown.
Caution
|
|---|
|
An abandoned mutex often indicates a serious error in the code. When a thread exits without releasing the mutex, the data structures protected by the mutex might not be in a consistent state. The next thread to request ownership of the mutex can handle this exception and proceed, if the integrity of the data structures can be verified. |
In the case of a system-wide mutex, an abandoned mutex might indicate that an application has been terminated abruptly (for example, by using Windows Task Manager).
The following example shows how a local Mutex object is used to synchronize access to a protected resource. The thread that creates the mutex does not own it initially. The ReleaseMutex method is used to release the mutex when it is no longer needed.
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. using System; using System.Threading; class Test { // Create a new Mutex. The creating thread does not own the // Mutex. private static Mutex mut = new Mutex(); private const int numIterations = 1; private const int numThreads = 3; static void Main() { // Create the threads that will use the protected resource. for(int i = 0; i < numThreads; i++) { Thread myThread = new Thread(new ThreadStart(MyThreadProc)); myThread.Name = String.Format("Thread{0}", i + 1); myThread.Start(); } // The main thread exits, but the application continues to // run until all foreground threads have exited. } private static void MyThreadProc() { for(int i = 0; i < numIterations; i++) { UseResource(); } } // This method represents a resource that must be synchronized // so that only one thread at a time can enter. private static void UseResource() { // Wait until it is safe to enter. mut.WaitOne(); Console.WriteLine("{0} has entered the protected area", Thread.CurrentThread.Name); // Place code to access non-reentrant resources here. // Simulate some work. Thread.Sleep(500); Console.WriteLine("{0} is leaving the protected area\r\n", Thread.CurrentThread.Name); // Release the Mutex. mut.ReleaseMutex(); } }
Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2
The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
The explanation on Mutex.ReleaseMutex() is very vague.
Here are the ones.
"Releases the Mutex once."
" The number of calls is kept by the common language runtime. The thread must call ReleaseMutex the same number of times to release ownership of the mutex."
In "Examples". it says,
"The ReleaseMutex method is used to release the mutex when it is no longer needed. "
As you can see, it's not clear what "release" means.
There can be many.
1. Cleaning up memory
Release a memory for the Mutex class.
However, for this there is Dispose(). So, here "release" would not mean to clear up memory space allocated by "Mutex m_mutex = new Mutex(false)", for example.
2. Release ownership
Because it acquires ownership of a mutex when calling Mutex.WaitOne().
As in the 2nd explanation above, the document says "to release ownership of the mutex". So, I think calling ReleaseMutex() is to hand off from owning of the mutex. However, it's not clear because in other lines of the same document it sounds like release of memory space.
3. Does "ReleaseMutex()" signals the Mutex?
The document failed in explaining any subsquent behavior by calling ReleaseMutex().
In my design, I set a callback by WlanRegisterNotification(). So, in the triggered notification function ( which is in different thread than the main thread ), it calls WaitOne() and ReleaseOne(). And in the main thread, when a user clicks "disconnect" button, it tries to unregister the notification, disconnect from a WIFI and closes the handle. However, when the notification handle tries to print out a message using Invoke() mechanism, it can go into the main thread to actually access a TextBox control and modify content in it. Because "Invoke()" causes to call a method on a main thread's space, It can conflict in calling WlanDisconnect(), WlanClose().
( I debugged it and it happened. ) So, that is why protected the two area of codes with WaitOne() and ReleaseOne(). ( One where the triggered function tries to put some text on TextBox control and the other where the main thread to cease the connection. )
Example of AppendLogMessage(), which is called from the triggered function ( which runs on a thread created by the system for callback mechanism. )
// from a triggerred function
private void AppendLogMessage(string message)
{
if (this.m_messageTextBox.InvokeRequired)
{
m_messageMutex.WaitOne();
AppendMessageCallback callback = new AppendMessageCallback(AppendLogMessage);
this.Invoke(callback, new object[] { message });
m_messageMutex.ReleaseMutex();
}
else
m_messageTextBox.AppendText(message + Environment.NewLine);
from a main thread
private void m_disconnectButton_Click(object sender, EventArgs e)
{
UInt32 errorNum;
if (m_clientHandle != IntPtr.Zero)
{
NativeWIFIAPIs.WLAN_NOTIFICATION_SOURCE prevSource;
m_messageMutex.WaitOne();
NativeWIFIAPIs.WlanRegisterNotification(m_clientHandle, NativeWIFIAPIs.WLAN_NOTIFICATION_SOURCE.None, true,
(NativeWIFIAPIs.WLAN_NOTIFICATION_CALLBACK)(null), IntPtr.Zero, IntPtr.Zero, out prevSource);
errorNum = NativeWIFIAPIs.WlanDisconnect(m_clientHandle, ref m_interfaceGUID, IntPtr.Zero);
errorNum = NativeWIFIAPIs.WlanCloseHandle(m_clientHandle, IntPtr.Zero);
m_clientHandle = IntPtr.Zero;
m_messageMutex.ReleaseMutex();
AppendLogMessage("Disconnected." + Environment.NewLine);
}
}
Based on context of mutex ( based on my experience with Win32, Mac, Linux, various Unix ), if one thread gives up the ownership of the mutex, other thread should be able to acquire it when the "other" thread calls "WaitOne()" for example.
Then without explicitly "signaling" the synchronization object, which is an instance of the Mutex, releasing the ownership of a mutex should signal the mutex if you guys implemented mutex as a subclass of WaitHandle.
However this is not clear in addition to "Releasing" the mutex.
I assume that the "signaling" is done automatically by WaitOne() and ReleaseMutex() appropriately when the Mutex is auto-reseting one. However it doesn't seem to work.
- 5/16/2012
- JongAm Park
Caution