Mutex.ReleaseMutex Método
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Libera una vez la instancia de Mutex.
public:
void ReleaseMutex();
public void ReleaseMutex ();
member this.ReleaseMutex : unit -> unit
Public Sub ReleaseMutex ()
Excepciones
El subproceso que realiza la llamada no posee la exclusión mutua.
Ya se ha eliminado la instancia actual.
Ejemplos
En el ejemplo siguiente se muestra cómo se usa un objeto local Mutex para sincronizar el acceso a un recurso protegido. El subproceso que crea la exclusión mutua no lo posee inicialmente. El ReleaseMutex método se usa para liberar la exclusión mutua cuando ya no es necesario.
// 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 namespace System;
using namespace System::Threading;
const int numIterations = 1;
const int numThreads = 3;
ref class Test
{
public:
// Create a new Mutex. The creating thread does not own the
// Mutex.
static Mutex^ mut = gcnew Mutex;
static void MyThreadProc()
{
for ( int i = 0; i < numIterations; i++ )
{
UseResource();
}
}
private:
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
static void UseResource()
{
//Wait until it is OK to enter.
mut->WaitOne();
Console::WriteLine( "{0} has entered protected the area", Thread::CurrentThread->Name );
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread::Sleep( 500 );
Console::WriteLine( "{0} is leaving protected the area\r\n", Thread::CurrentThread->Name );
// Release the Mutex.
mut->ReleaseMutex();
}
};
int main()
{
// Create the threads that will use the protected resource.
for ( int i = 0; i < numThreads; i++ )
{
Thread^ myThread = gcnew Thread( gcnew ThreadStart( Test::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.
}
// 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 Test13
{
// 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();
}
}
' 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.
Imports System.Threading
Class Test
' Create a new Mutex. The creating thread does not own the
' Mutex.
Private Shared mut As New Mutex()
Private Const numIterations As Integer = 1
Private Const numThreads As Integer = 3
<MTAThread> _
Shared Sub Main()
' Create the threads that will use the protected resource.
Dim i As Integer
For i = 1 To numThreads
Dim myThread As New Thread(AddressOf MyThreadProc)
myThread.Name = [String].Format("Thread{0}", i)
myThread.Start()
Next i
' The main thread exits, but the application continues to
' run until all foreground threads have exited.
End Sub
Private Shared Sub MyThreadProc()
Dim i As Integer
For i = 1 To numIterations
UseResource()
Next i
End Sub
' This method represents a resource that must be synchronized
' so that only one thread at a time can enter.
Private Shared Sub UseResource()
' Wait until it is safe to enter.
mut.WaitOne()
Console.WriteLine("{0} has entered protected area", _
Thread.CurrentThread.Name)
' Place code to access non-reentrant resources here.
' Simulate some work
Thread.Sleep(500)
Console.WriteLine("{0} is leaving protected area" & vbCrLf, _
Thread.CurrentThread.Name)
' Release Mutex.
mut.ReleaseMutex()
End Sub
End Class
Comentarios
Cada vez que un subproceso adquiere una exclusión mutua (por ejemplo, llamando a su WaitOne método), debe llamar ReleaseMutex posteriormente a para renunciar a la propiedad de la exclusión mutua y desbloquear otros subprocesos que intentan obtener la propiedad de la exclusión mutua. Si se produce un error en el intento de obtener la propiedad de la exclusión mutua (por ejemplo, cuando se devuelve false
una llamada al WaitOne método con un millisecondsTimeout
parámetro o porque timeout
la solicitud agota el tiempo de espera), el subproceso no debe llamar a ReleaseMutex, en este caso, el subproceso tampoco debe permitirse tener acceso al recurso protegido por la exclusión mutua, como se muestra en el ejemplo siguiente.
using System;
using System.Threading;
class Example
{
// 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()
{
Example ex = new Example();
ex.StartThreads();
}
private void StartThreads()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread returns to Main and exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
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, and do not enter if the request times out.
Console.WriteLine("{0} is requesting the mutex", Thread.CurrentThread.Name);
if (mut.WaitOne(1000)) {
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(5000);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
else {
Console.WriteLine("{0} will not acquire the mutex",
Thread.CurrentThread.Name);
}
}
~Example()
{
mut.Dispose();
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread1 has entered the protected area
// Thread2 is requesting the mutex
// Thread3 is requesting the mutex
// Thread2 will not acquire the mutex
// Thread3 will not acquire the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
Imports System.Threading
Class Example
' Create a new Mutex. The creating thread does not own the mutex.
Private mut As New Mutex()
Private Const numIterations As Integer = 1
Private Const numThreads As Integer = 3
Public Shared Sub Main()
Dim ex As New Example()
ex.StartThreads()
End Sub
Private Sub StartThreads()
' Create the threads that will use the protected resource.
For i As Integer = 0 To numThreads - 1
Dim newThread As New Thread(AddressOf ThreadProc)
newThread.Name = String.Format("Thread{0}", i + 1)
newThread.Start()
Next
' The main thread returns to Main and exits, but the application continues to
' run until all foreground threads have exited.
End Sub
Private Sub ThreadProc()
For i As Integer = 0 To numIterations - 1
UseResource()
Next
End Sub
' This method represents a resource that must be synchronized
' so that only one thread at a time can enter.
Private Sub UseResource()
' Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name)
If mut.WaitOne(1000) Then
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name)
' Place code to access non-reentrant resources here.
' Simulate some work.
Thread.Sleep(5000)
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name)
' Release the Mutex.
mut.ReleaseMutex()
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name)
Else
Console.WriteLine("{0} will not acquire the mutex",
Thread.CurrentThread.Name)
End If
End Sub
Protected Overrides Sub Finalize()
mut.Dispose()
End Sub
End Class
' The example displays output like the following:
' Thread1 is requesting the mutex
' Thread1 has entered the protected area
' Thread2 is requesting the mutex
' Thread3 is requesting the mutex
' Thread2 will not acquire the mutex
' Thread3 will not acquire the mutex
' Thread1 is leaving the protected area
' Thread1 has released the mutex
Un subproceso que posee una exclusión mutua puede especificar la misma exclusión mutua en llamadas de función de espera repetidas sin bloquear su ejecución. Common Language Runtime mantiene el número de llamadas. El subproceso debe llamar al ReleaseMutex mismo número de veces para liberar la propiedad de la exclusión mutua.
Si un subproceso finaliza mientras posee una exclusión mutua, se dice que la exclusión mutua se abandona. El estado de la exclusión mutua se establece en señalado y el siguiente subproceso en espera obtiene la propiedad. Si nadie posee la exclusión mutua, se señala el estado de la exclusión mutua. A partir de la versión 2.0 de .NET Framework, se produce una AbandonedMutexException excepción en el siguiente subproceso que adquiere la exclusión mutua. Antes de la versión 2.0 de .NET Framework, no se produjo ninguna excepción.
Precaución
Una exclusión mutua abandonada suele indicar un error grave en el código. Cuando un subproceso sale sin liberar la exclusión mutua, es posible que las estructuras de datos protegidas por la exclusión mutua no estén en un estado coherente. El siguiente subproceso para solicitar la propiedad de la exclusión mutua puede controlar esta excepción y continuar, si se puede comprobar la integridad de las estructuras de datos.
En el caso de una exclusión mutua en todo el sistema, una exclusión mutua abandonada podría indicar que una aplicación finalizó inesperadamente (por ejemplo, con el Administrador de tareas de Windows).