Mutex Classe

Définition

Primitive de synchronisation qui peut également être utilisée pour la synchronisation entre processus.

public ref class Mutex sealed : System::Threading::WaitHandle
public sealed class Mutex : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Mutex : System.Threading.WaitHandle
type Mutex = class
    inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(true)>]
type Mutex = class
    inherit WaitHandle
Public NotInheritable Class Mutex
Inherits WaitHandle
Héritage
Héritage
Attributs

Exemples

Cet exemple montre comment un Mutex objet local est utilisé pour synchroniser l’accès à une ressource protégée. Étant donné que chaque thread appelant est bloqué jusqu’à ce qu’il acquière la propriété du mutex, il doit appeler la ReleaseMutex méthode pour libérer la propriété du mutex.

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()
    {
        // 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 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.
        Console.WriteLine("{0} is requesting the mutex", 
                          Thread.CurrentThread.Name);
        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", 
            Thread.CurrentThread.Name);

        // Release the Mutex.
        mut.ReleaseMutex();
        Console.WriteLine("{0} has released the mutex", 
            Thread.CurrentThread.Name);
    }
}
// The example displays output like the following:
//       Thread1 is requesting the mutex
//       Thread2 is requesting the mutex
//       Thread1 has entered the protected area
//       Thread3 is requesting the mutex
//       Thread1 is leaving the protected area
//       Thread1 has released the mutex
//       Thread3 has entered the protected area
//       Thread3 is leaving the protected area
//       Thread3 has released the mutex
//       Thread2 has entered the protected area
//       Thread2 is leaving the protected area
//       Thread2 has released the mutex
Imports System.Threading

Module 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 Sub Main()
        ' 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 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)
        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", 
            Thread.CurrentThread.Name)

        ' Release the Mutex.
        mut.ReleaseMutex()
        Console.WriteLine("{0} has released the mutex", 
            Thread.CurrentThread.Name)
   End Sub
End Module
' The example displays output like the following:
'       Thread1 is requesting the mutex
'       Thread2 is requesting the mutex
'       Thread1 has entered the protected area
'       Thread3 is requesting the mutex
'       Thread1 is leaving the protected area
'       Thread1 has released the mutex
'       Thread3 has entered the protected area
'       Thread3 is leaving the protected area
'       Thread3 has released the mutex
'       Thread2 has entered the protected area
'       Thread2 is leaving the protected area
'       Thread2 has released the mutex

Dans l’exemple suivant, chaque thread appelle la WaitOne(Int32) méthode pour acquérir le mutex. Si l’intervalle de délai d’attente est écoulé, la méthode retourne false et le thread n’acquiert pas le mutex et n’obtient pas l’accès à la ressource protégée par le mutex. La ReleaseMutex méthode est appelée uniquement par le thread qui acquiert le mutex.

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

Remarques

Lorsque plusieurs threads ont besoin d’accéder à une ressource partagée en même temps, le système a besoin d’un mécanisme de synchronisation pour s’assurer qu’un seul thread à la fois utilise la ressource. Mutex est une primitive de synchronisation qui accorde un accès exclusif à la ressource partagée à un seul thread. Si un thread acquiert un mutex, le deuxième thread qui souhaite acquérir ce mutex est suspendu jusqu’à ce que le premier thread libère le mutex.

Important

Ce type implémente l'interface IDisposable. Une fois que vous avez fini d’utiliser le type, vous devez le supprimer directement ou indirectement. Pour supprimer directement le type Dispose, appelez sa méthode dans un bloc try/catch. Pour la supprimer indirectement, utilisez une construction de langage telle que using (dans C#) ou Using (dans Visual Basic). Pour plus d’informations, consultez la section « Utilisation d’un objet qui implémente IDisposable » dans la rubrique de l’interface IDisposable.

Vous pouvez utiliser la WaitHandle.WaitOne méthode pour demander la propriété d’un mutex. Le thread appelant se bloque jusqu’à ce que l’un des éléments suivants se produise :

  • Le mutex est signalé pour indiquer qu’il n’est pas détenu. Dans ce cas, la WaitOne méthode retourne true et le thread appelant assume la propriété du mutex et accède à la ressource protégée par le mutex. Lorsqu’il a terminé d’accéder à la ressource, le thread doit appeler la ReleaseMutex méthode pour libérer la propriété du mutex. Le premier exemple de la section exemples illustre ce modèle.

  • L’intervalle de délai d’attente spécifié dans l’appel à une WaitOne méthode qui a millisecondsTimeout un timeout paramètre ou a expiré. Dans ce cas, la WaitOne méthode retourne false et le thread appelant ne tente pas d’acquérir la propriété du mutex. Dans ce cas, vous devez structurer votre code pour que l’accès à la ressource protégée par le mutex soit refusé au thread appelant. Étant donné que le thread n’a jamais acquis la propriété du mutex, il ne doit pas appeler la ReleaseMutex méthode. Le deuxième exemple de la section exemples illustre ce modèle.

La Mutex classe applique l’identité de thread, donc un mutex peut être libéré uniquement par le thread qui l’a acquis. En revanche, la Semaphore classe n’applique pas l’identité des threads. Un mutex peut également être passé au-delà des limites du domaine d’application.

Le thread qui possède un mutex peut demander le même Mutex dans des appels répétés à WaitOne sans bloquer son exécution. Toutefois, le thread doit appeler la ReleaseMutex méthode le même nombre de fois pour libérer la propriété du mutex.

Étant donné que la Mutex classe hérite de WaitHandle , vous pouvez également appeler les WaitHandle.WaitAll méthodes et statiques WaitHandle.WaitAny pour synchroniser l’accès à une ressource protégée.

Si un thread se termine alors qu’il est propriétaire d’un mutex, le mutex est considéré comme abandonné. L’état du mutex est défini sur signalé et le thread en attente suivant obtient la propriété. à compter de la version 2,0 du .NET Framework, une AbandonedMutexException exception est levée dans le thread suivant qui acquiert le mutex abandonné. avant la version 2,0 de la .NET Framework, aucune exception n’a été levée.

Attention

Un mutex abandonné indique souvent une erreur grave dans le code. Lorsqu’un thread se termine sans libérer le mutex, les structures de données protégées par le mutex risquent de 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).

Les mutex sont de deux types : les mutex locaux, qui sont sans nom et les mutex système nommés. Un mutex local existe uniquement dans votre processus. Il peut être utilisé par tout thread de votre processus qui a une référence à l' Mutex objet qui représente le mutex. Chaque objet sans nom Mutex représente un mutex local distinct.

Les mutex système nommés sont visibles dans tout le système d’exploitation et peuvent être utilisés pour synchroniser les activités des processus. Vous pouvez créer un Mutex objet qui représente un mutex système nommé à l’aide d’un constructeur qui accepte un nom. L’objet de système d’exploitation peut être créé en même temps, ou il peut exister avant la création de l' Mutex objet. Vous pouvez créer plusieurs objets Mutex qui représentent le même mutex de système nommé, et vous pouvez utiliser la méthode OpenExisting pour ouvrir un mutex de système nommé existant.

Notes

Sur un serveur qui exécute les services Terminal Server, un mutex système nommé peut avoir deux niveaux de visibilité. Si son nom commence par le préfixe « global \ », le mutex est visible dans toutes les sessions Terminal Server. Si son nom commence par le préfixe « local \ », le mutex est visible uniquement dans la session Terminal Server dans laquelle il a été créé. Dans ce cas, un mutex distinct du même nom peut exister dans chacune des autres sessions Terminal Server sur le serveur. Si vous ne spécifiez pas de préfixe lorsque vous créez un mutex nommé, il prend le préfixe « local \ ». Dans une session Terminal Server, deux mutex dont les noms diffèrent uniquement par leurs préfixes sont des mutex distincts, et les deux sont visibles par tous les processus de la session Terminal Server. Autrement dit, les noms de préfixe « global \ » et « local \ » décrivent l’étendue du nom de mutex par rapport aux sessions Terminal Server, et non par rapport aux processus.

La barre oblique inverse (\) est un caractère réservé dans un nom de mutex. N’utilisez pas de barre oblique inverse (\) dans un nom de mutex, sauf si spécifié dans la remarque sur l’utilisation de mutex dans les sessions Terminal Server. Sinon, une DirectoryNotFoundException peut être levée, même si le nom du mutex représente un fichier existant.

Constructeurs

Mutex()

Initialise une nouvelle instance de la classe Mutex avec des propriétés par défaut.

Mutex(Boolean)

Initialise une nouvelle instance de la classe Mutex avec une valeur booléenne qui indique si le thread appelant doit avoir la propriété initiale du mutex.

Mutex(Boolean, String)

Initialise une nouvelle instance de la classe Mutex avec une valeur booléenne qui indique si le thread appelant doit avoir la propriété initiale du mutex, et une chaîne représentant le nom du mutex.

Mutex(Boolean, String, Boolean)

Initialise une nouvelle instance de la classe Mutex avec une valeur booléenne qui indique si le thread appelant doit avoir la propriété initiale du mutex, une chaîne qui représente le nom du mutex et une valeur booléenne qui, quand la méthode retourne son résultat, indique si la propriété initiale du mutex a été accordée au thread appelant.

Mutex(Boolean, String, Boolean, MutexSecurity)

Initialise une nouvelle instance de la classe Mutex avec une valeur booléenne qui indique si le thread appelant doit avoir la propriété initiale du mutex, une chaîne qui représente le nom du mutex et une variable booléenne qui, quand la méthode retourne son résultat, indique si la propriété initiale du mutex a été accordée au thread appelant, ainsi que la sécurité de contrôle d'accès à appliquer au mutex nommé.

Champs

WaitTimeout

Indique que le délai fixé pour une opération WaitAny(WaitHandle[], Int32, Boolean) a été dépassé sans qu'aucun des handles d'attente n'ait été signalé. Ce champ est constant.

(Hérité de WaitHandle)

Propriétés

Handle
Obsolète.
Obsolète.

Obtient ou définit le handle du système d'exploitation natif.

(Hérité de WaitHandle)
SafeWaitHandle

Obtient ou définit le handle du système d'exploitation natif.

(Hérité de WaitHandle)

Méthodes

Close()

Libère toutes les ressources détenues par le WaitHandle actuel.

(Hérité de WaitHandle)
CreateObjRef(Type)

Crée un objet contenant toutes les informations appropriées requises pour générer un proxy permettant de communiquer avec un objet distant.

(Hérité de MarshalByRefObject)
Dispose()

Libère toutes les ressources utilisées par l'instance actuelle de la classe WaitHandle.

(Hérité de WaitHandle)
Dispose(Boolean)

En cas de substitution dans une classe dérivée, libère les ressources non managées utilisées par WaitHandle et libère éventuellement les ressources managées.

(Hérité de WaitHandle)
Equals(Object)

Détermine si l'objet spécifié est égal à l'objet actuel.

(Hérité de Object)
GetAccessControl()

Obtient un objet MutexSecurity qui représente la sécurité de contrôle d'accès pour le mutex nommé.

GetHashCode()

Fait office de fonction de hachage par défaut.

(Hérité de Object)
GetLifetimeService()
Obsolète.

Récupère l'objet de service de durée de vie en cours qui contrôle la stratégie de durée de vie de cette instance.

(Hérité de MarshalByRefObject)
GetType()

Obtient le Type de l'instance actuelle.

(Hérité de Object)
InitializeLifetimeService()
Obsolète.

Obtient un objet de service de durée de vie pour contrôler la stratégie de durée de vie de cette instance.

(Hérité de MarshalByRefObject)
MemberwiseClone()

Crée une copie superficielle du Object actuel.

(Hérité de Object)
MemberwiseClone(Boolean)

Crée une copie superficielle de l'objet MarshalByRefObject actuel.

(Hérité de MarshalByRefObject)
OpenExisting(String)

Ouvre le mutex nommé spécifié, s'il existe déjà.

OpenExisting(String, MutexRights)

Ouvre le mutex nommé spécifié, s'il existe déjà, avec l'accès de sécurité souhaité.

ReleaseMutex()

Libère l'objet Mutex une seule fois.

SetAccessControl(MutexSecurity)

Définit la sécurité de contrôle d'accès pour un mutex système nommé.

ToString()

Retourne une chaîne qui représente l'objet actuel.

(Hérité de Object)
TryOpenExisting(String, Mutex)

Ouvre le mutex nommé spécifié, s'il existe déjà, et retourne une valeur indiquant si l'opération a réussi.

TryOpenExisting(String, MutexRights, Mutex)

Ouvre le mutex nommé spécifié, s'il existe déjà, avec l'accès de sécurité souhaité, puis retourne une valeur indiquant si l'opération a réussi.

WaitOne()

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal.

(Hérité de WaitHandle)
WaitOne(Int32)

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l'intervalle de temps.

(Hérité de WaitHandle)
WaitOne(Int32, Boolean)

Bloque le thread actuel jusqu’à ce que le WaitHandle actuel reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l’intervalle de temps et en spécifiant s’il faut quitter le domaine de synchronisation avant l’attente.

(Hérité de WaitHandle)
WaitOne(TimeSpan)

Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps.

(Hérité de WaitHandle)
WaitOne(TimeSpan, Boolean)

Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.

(Hérité de WaitHandle)

Implémentations d’interfaces explicites

IDisposable.Dispose()

Cette API prend en charge l'infrastructure du produit et n'est pas destinée à être utilisée directement à partir de votre code.

Libère toutes les ressources utilisées par WaitHandle.

(Hérité de WaitHandle)

Méthodes d’extension

GetAccessControl(Mutex)

Retourne les descripteurs de sécurité pour le mutex spécifié.

SetAccessControl(Mutex, MutexSecurity)

Définit les descripteurs de sécurité pour le mutex spécifié.

GetSafeWaitHandle(WaitHandle)

Obtient le handle sécurisé pour un handle d’attente de système d’exploitation natif.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Définit un handle sécurisé pour un handle d’attente de système d’exploitation natif.

S’applique à

Cohérence de thread

Ce type est thread-safe.

Voir aussi