Mutex.ReleaseMutex Método
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Libera o Mutex uma vez.
public:
void ReleaseMutex();
public void ReleaseMutex ();
member this.ReleaseMutex : unit -> unit
Public Sub ReleaseMutex ()
Exceções
O thread de chamada não tem o mutex.
A instância atual já foi descartada.
Exemplos
O exemplo a seguir mostra como um objeto local Mutex é usado para sincronizar o acesso a um recurso protegido. O thread que cria o mutex não o possui inicialmente. O ReleaseMutex método é usado para liberar o mutex quando ele não é mais necessário.
// 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
Comentários
Sempre que um thread adquire um mutex (por exemplo, chamando seu WaitOne método), ele deve, posteriormente, chamar ReleaseMutex para abrir mão da propriedade do mutex e desbloquear outros threads que estão tentando obter a propriedade do mutex. Se a tentativa de obter a propriedade do mutex falhar (por exemplo, quando uma chamada para o WaitOne método com um millisecondsTimeout
ou um timeout
parâmetro retornar false
porque a solicitação atinge o tempo limite), o thread não deve chamar ReleaseMutex, nesse caso, o thread também não deve ter permissão para acessar o recurso protegido pelo mutex, como mostra o exemplo a seguir.
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
Um thread que possui um mutex pode especificar o mesmo mutex em chamadas de função de espera repetidas sem bloquear sua execução. O número de chamadas é mantido pelo common language runtime. O thread deve chamar ReleaseMutex o mesmo número de vezes para liberar a propriedade do mutex.
Se um thread terminar enquanto possui um mutex, o mutex será abandonado. O estado do mutex é definido como sinalizado e o próximo thread de espera obtém a propriedade. Se ninguém tiver o mutex, o estado do mutex será sinalizado. A partir da versão 2.0 do .NET Framework, um AbandonedMutexException é lançado no próximo thread que adquire o mutex. Antes da versão 2.0 do .NET Framework, nenhuma exceção foi gerada.
Cuidado
Um mutex abandonado geralmente indica um erro grave no código. Quando um thread sai sem liberar o mutex, as estruturas de dados protegidas pelo mutex podem não estar em um estado consistente. O próximo thread a solicitar a propriedade do mutex poderá lidar com essa exceção e prosseguir, se a integridade das estruturas de dados puder ser verificada.
No caso de um mutex de todo o sistema, um mutex abandonado pode indicar que um aplicativo foi finalizado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows).