Mutex.ReleaseMutex Metoda
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Uvolní jednou Mutex .
public:
void ReleaseMutex();
public void ReleaseMutex ();
member this.ReleaseMutex : unit -> unit
Public Sub ReleaseMutex ()
Výjimky
Volající vlákno nevlastní mutex.
Aktuální instance již byla odstraněna.
Příklady
Následující příklad ukazuje, jak se místní Mutex objekt používá k synchronizaci přístupu k chráněnému prostředku. Vlákno, které vytvoří mutex, ho zpočátku nevlastní. Metoda ReleaseMutex se používá k uvolnění mutexu, pokud už není potřeba.
// 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
Poznámky
Pokaždé, když vlákno získá mutex (například voláním jeho WaitOne metody), musí následně volat ReleaseMutex ke změně vlastnictví mutexu a odblokovat další vlákna, která se snaží získat vlastnictví mutexu. Pokud se pokus o získání vlastnictví mutexu nezdaří (například když volání WaitOne metody s millisecondsTimeout
parametrem nebo timeout
parametrem vyprší false
, protože vypršel časový limit požadavku), vlákno by nemělo volat ReleaseMutex, v tomto případě by vlákno také nemělo mít povolený přístup k prostředku chráněnému mutexem, jak ukazuje následující příklad.
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
Vlákno, které vlastní mutex, může určit stejný mutex v opakovaných voláních funkce čekání bez blokování jeho spuštění. Počet volání je udržován modulem CLR (Common Language Runtime). Vlákno musí volat ReleaseMutex stejný počet, kolikrát uvolní vlastnictví mutexu.
Pokud vlákno ukončí při vlastnictví mutexu, mutex se říká, že je opuštěný. Stav mutexu je nastavený tak, aby signalizoval a další čekající vlákno získá vlastnictví. Pokud nikdo nevlastní mutex, stav mutexu se signalizují. Počínaje verzí 2.0 rozhraní .NET Framework AbandonedMutexException je vyvolán v dalším vlákně, které získá mutex. Před verzí 2.0 rozhraní .NET Framework nebyla vyvolán žádná výjimka.
Upozornění
Opuštěný mutex často označuje závažnou chybu v kódu. Když vlákno opustí bez uvolnění mutexu, datové struktury chráněné mutexem nemusí být v konzistentním stavu. Další vlákno pro vyžádání vlastnictví mutex může tuto výjimku zpracovat a pokračovat, pokud je možné ověřit integritu datových struktur.
V případě mutexu celého systému může opuštěný mutex znamenat, že aplikace byla náhle ukončena (například pomocí Windows Správce úloh).