Mutex.ReleaseMutex Méthode
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Libère l'objet Mutex une seule fois.
public:
void ReleaseMutex();
public void ReleaseMutex ();
member this.ReleaseMutex : unit -> unit
Public Sub ReleaseMutex ()
Exceptions
Le thread appelant ne possède pas le mutex.
L’instance actuelle a déjà été supprimée.
Exemples
L’exemple suivant montre comment un objet local Mutex est utilisé pour synchroniser l’accès à une ressource protégée. Le thread qui crée le mutex ne le possède pas initialement. La ReleaseMutex méthode est utilisée pour libérer le mutex lorsqu’il n’est plus nécessaire.
// 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
Remarques
Chaque fois qu’un thread acquiert un mutex (par exemple, en appelant sa WaitOne méthode), il doit ensuite appeler ReleaseMutex pour abandonner la propriété du mutex et débloquer d’autres threads qui tentent d’obtenir la propriété du mutex. Si la tentative d’obtention de la propriété du mutex échoue (par exemple, lorsqu’un appel à la WaitOne méthode avec un millisecondsTimeout
ou un timeout
paramètre retourne false
parce que la requête expire), le thread ne doit pas appeler ReleaseMutex, dans ce cas, le thread ne doit pas être autorisé à accéder à la ressource protégée par le mutex, comme l’illustre l’exemple suivant.
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 thread propriétaire d’un mutex peut spécifier le même mutex dans les appels de fonction d’attente répétés sans bloquer son exécution. Le nombre d’appels est conservé par le Common Language Runtime. Le thread doit appeler ReleaseMutex le même nombre de fois pour libérer la propriété du mutex.
Si un thread se termine lors de la propriété d’un mutex, le mutex est dit abandonné. L’état du mutex est défini sur signalé et le thread en attente suivant obtient la propriété. Si personne ne possède le mutex, l’état du mutex est signalé. À compter de la version 2.0 du .NET Framework, un AbandonedMutexException élément est levée dans le thread suivant qui acquiert le mutex. Avant la version 2.0 du .NET Framework, aucune exception n’a été levée.
Attention
Un mutex abandonné indique souvent une erreur grave dans le code. Lorsqu’un thread quitte sans libérer le mutex, les structures de données protégées par le mutex peuvent ne pas être dans un état cohérent. Le thread suivant pour demander la propriété du mutex peut gérer cette exception et continuer, si l’intégrité des structures de données peut être vérifiée.
Si le mutex est développé au niveau système, et qu’il est abandonné, cela peut indiquer qu’une application a été arrêtée soudainement (par exemple, à l’aide du Gestionnaire des tâches de Windows).