Mutex クラス

定義

同期プリミティブは、プロセス間の同期にも使用できます。

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
継承
継承
属性

この例では、保護されたリソースへのアクセスを同期するためにローカル Mutex オブジェクトを使用する方法を示します。 呼び出し元の各スレッドはミューテックスの所有権を取得するまでブロックされるため、ミューテックスの所有権を ReleaseMutex 解放するにはメソッドを呼び出す必要があります。

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

次の例では、各スレッドがメソッドを WaitOne(Int32) 呼び出してミューテックスを取得します。 タイムアウト間隔が経過した場合、メソッドはミューテックスを取得 falseせず、ミューテックスが保護するリソースへのアクセスも取得しません。 このメソッドは ReleaseMutex 、ミューテックスを取得するスレッドによってのみ呼び出されます。

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

注釈

2 つ以上のスレッドが同時に共有リソースにアクセスする必要がある場合、システムには、一度に 1 つのスレッドのみがリソースを使用するように同期メカニズムが必要です。 Mutex は、共有リソースへの排他アクセスを 1 つのスレッドのみに付与する同期プリミティブです。 スレッドがミューテックスを取得した場合、そのミューテックスを取得する 2 番目のスレッドは、最初のスレッドがミューテックスを解放するまで中断されます。

重要

この型は IDisposable インターフェイスを実装します。 型の使用が完了したら、直接的または間接的に型を破棄する必要があります。 直接的に型を破棄するには、try/catch ブロック内で Dispose メソッドを呼び出します。 間接的に型を破棄するには、using (C# の場合) または Using (Visual Basic 言語) などの言語構成要素を使用します。 詳細については、IDisposable インターフェイスに関するトピック内の「IDisposable を実装するオブジェクトの使用」セクションを参照してください。

このメソッドを WaitHandle.WaitOne 使用して、ミューテックスの所有権を要求できます。 呼び出し元のスレッドは、次のいずれかが発生するまでブロックします。

  • ミューテックスは、所有されていないことを示すために通知されます。 この場合、メソッドは WaitOne 戻り true、呼び出し元のスレッドはミューテックスの所有権を引き受け、ミューテックスによって保護されているリソースにアクセスします。 リソースへのアクセスが完了したら、スレッドはメソッドを呼び出 ReleaseMutex してミューテックスの所有権を解放する必要があります。 「例」セクションの最初の例は、このパターンを示しています。

  • メソッドまたはtimeoutパラメーターを持つmillisecondsTimeoutメソッドのWaitOne呼び出しで指定されたタイムアウト間隔が経過しました。 この場合、メソッドは WaitOne 戻り false、呼び出し元のスレッドはミューテックスの所有権を取得しようとしません。 この場合は、ミューテックスによって保護されているリソースへのアクセスが呼び出し元のスレッドに対して拒否されるようにコードを構成する必要があります。 スレッドはミューテックスの所有権を取得しなかったため、メソッドを ReleaseMutex 呼び出してはなりません。 「例」セクションの 2 番目の例は、このパターンを示しています。

このクラスは Mutex スレッド ID を適用するため、ミューテックスは、それを取得したスレッドのみが解放できます。 これに対し Semaphore 、このクラスではスレッド ID は適用されません。 ミューテックスは、アプリケーション ドメインの境界を越えて渡すこともできます。

ミューテックスを所有するスレッドは、実行をブロックすることなく、繰り返し呼び出しで同じミューテックスを WaitOne 要求できます。 ただし、ミューテックスの所有権を解放するには、スレッドが ReleaseMutex 同じ回数だけメソッドを呼び出す必要があります。

クラスは Mutex 継承されるため WaitHandle、静的 WaitHandle.WaitAll メソッドと WaitHandle.WaitAny メソッドを呼び出して、保護されたリソースへのアクセスを同期することもできます。

ミューテックスの所有中にスレッドが終了すると、ミューテックスは破棄されると言われます。 ミューテックスの状態がシグナルに設定され、次の待機中のスレッドが所有権を取得します。 .NET Frameworkのバージョン 2.0 以降では、AbandonedMutexException破棄されたミューテックスを取得する次のスレッドで an がスローされます。 .NET Frameworkのバージョン 2.0 より前では、例外はスローされませんでした。

注意事項

破棄されたミューテックスは、多くの場合、コードで重大なエラーを示します。 ミューテックスを解放せずにスレッドが終了すると、ミューテックスによって保護されたデータ構造が一貫した状態にならない可能性があります。 ミューテックスの所有権を要求する次のスレッドは、この例外を処理し、データ構造の整合性を検証できる場合は続行できます。

システム全体でミューテックスが有効な場合にミューテックスが破棄されたときは、アプリケーションが強制終了されたことを示している可能性があります (たとえば、Windows タスク マネージャを使用した終了)。

ミューテックスは、名前のないローカル ミューテックスと名前付きシステム ミューテックスの 2 種類です。 ローカル ミューテックスは、現在のプロセス内にのみ存在します。 ミューテックスを表すオブジェクトへの参照を持つプロセス内の任意の Mutex スレッドで使用できます。 名前のない各オブジェクトは Mutex 、個別のローカル ミューテックスを表します。

名前付きシステム ミューテックスはオペレーティング システム全体で表示され、プロセスのアクティビティを同期するために使用できます。 名前を受け取るコンストラクターを Mutex 使用して、名前付きシステム ミューテックスを表すオブジェクトを作成できます。 オペレーティング システム オブジェクトは、同時に作成することも、オブジェクトを作成 Mutex する前に存在することもできます。 同じ名前付きシステム ミューテックスを表す複数の Mutex オブジェクトを作成できます。また、OpenExisting メソッドを使用して、既存の名前付きシステム ミューテックスを開くことができます。

注意

ターミナル サービスを実行しているサーバーでは、名前付きシステム ミューテックスに 2 つのレベルの可視性を設定できます。 名前がプレフィックス "Global\" で始まる場合、ミューテックスはすべてのターミナル サーバー セッションで表示されます。 名前がプレフィックス "Local\" で始まる場合、ミューテックスは作成されたターミナル サーバー セッションでのみ表示されます。 その場合、同じ名前の別のミューテックスが、サーバー上の他の各ターミナル サーバー セッションに存在する可能性があります。 名前付きミューテックスを作成するときにプレフィックスを指定しない場合は、プレフィックス "Local\" を受け取ります。 ターミナル サーバー セッション内では、名前がプレフィックスによってのみ異なる 2 つのミューテックスは個別のミューテックスであり、両方ともターミナル サーバー セッションのすべてのプロセスに表示されます。 つまり、プレフィックス名 "Global\" と "Local\" は、プロセスに対する相対ではなく、ターミナル サーバー セッションに対するミューテックス名のスコープを表します。

円記号 (\) は、ミューテックス名の予約文字です。 ターミナル サーバー セッションのミューテックス使用に関する注記に指定されていない限り、ミューテックス名に円記号 (\) を使用しないでください。 使用した場合、ミューテックスの名前が既存のファイルを表すとしても、DirectoryNotFoundException がスローされることがあります。

コンストラクター

Mutex()

Mutex クラスの新しいインスタンスを、既定のプロパティを使用して初期化します。

Mutex(Boolean)

呼び出し元のスレッドにミューテックスの初期所有権があるかどうかを示すブール値を使用して、Mutex クラスの新しいインスタンスを初期化します。

Mutex(Boolean, String)

呼び出し元のスレッドにミューテックスの初期所有権があるかどうかを示すブール値と、ミューテックスの名前を表す文字列を使用して、Mutex クラスの新しいインスタンスを初期化します。

Mutex(Boolean, String, Boolean)

呼び出し元のスレッドにミューテックスの初期所有権があるかどうかを示すブール値、ミューテックスの名前を表す文字列、およびメソッドから戻るときにミューテックスの初期所有権が呼び出し元のスレッドに付与されたかどうかを示すブール値を指定して、Mutex クラスの新しいインスタンスを初期化します。

Mutex(Boolean, String, Boolean, MutexSecurity)

呼び出し元のスレッドにミューテックスの初期所有権があるかどうかを示すブール値、ミューテックスの名前を表す文字列、メソッドが戻るときにミューテックスの初期所有権が呼び出し元のスレッドに付与されたかどうかを示すブール値変数、および名前付きミューテックスに適用するアクセス制御セキュリティを指定して、Mutex クラスの新しいインスタンスを初期化します。

フィールド

WaitTimeout

待機ハンドルがシグナル状態になる前に WaitAny(WaitHandle[], Int32, Boolean) 操作がタイムアウトになったことを示します。 このフィールドは定数です。

(継承元 WaitHandle)

プロパティ

Handle
互換性のために残されています。
互換性のために残されています。

ネイティブ オペレーティング システム ハンドルを取得または設定します。

(継承元 WaitHandle)
SafeWaitHandle

ネイティブ オペレーティング システム ハンドルを取得または設定します。

(継承元 WaitHandle)

メソッド

Close()

現在の WaitHandle によって保持されているすべてのリソースを解放します。

(継承元 WaitHandle)
CreateObjRef(Type)

リモート オブジェクトとの通信に使用するプロキシの生成に必要な情報をすべて格納しているオブジェクトを作成します。

(継承元 MarshalByRefObject)
Dispose()

WaitHandle クラスの現在のインスタンスによって使用されているすべてのリソースを解放します。

(継承元 WaitHandle)
Dispose(Boolean)

派生クラスでオーバーライドされると、WaitHandle によって使用されているアンマネージド リソースを解放し、オプションでマネージド リソースも解放します。

(継承元 WaitHandle)
Equals(Object)

指定されたオブジェクトが現在のオブジェクトと等しいかどうかを判断します。

(継承元 Object)
GetAccessControl()

名前付きミューテックスのアクセス制御セキュリティを表す MutexSecurity オブジェクトを取得します。

GetHashCode()

既定のハッシュ関数として機能します。

(継承元 Object)
GetLifetimeService()
互換性のために残されています。

対象のインスタンスの有効期間ポリシーを制御する、現在の有効期間サービス オブジェクトを取得します。

(継承元 MarshalByRefObject)
GetType()

現在のインスタンスの Type を取得します。

(継承元 Object)
InitializeLifetimeService()
互換性のために残されています。

このインスタンスの有効期間ポリシーを制御する有効期間サービス オブジェクトを取得します。

(継承元 MarshalByRefObject)
MemberwiseClone()

現在の Object の簡易コピーを作成します。

(継承元 Object)
MemberwiseClone(Boolean)

現在の MarshalByRefObject オブジェクトの簡易コピーを作成します。

(継承元 MarshalByRefObject)
OpenExisting(String)

既に存在する場合は、指定した名前付きミューテックスを開きます。

OpenExisting(String, MutexRights)

既に存在する場合は、必要なセキュリティ アクセスで指定した名前付きミューテックスを開きます。

ReleaseMutex()

Mutex を一度解放します。

SetAccessControl(MutexSecurity)

名前付きシステム ミューテックスのアクセス制御セキュリティを設定します。

ToString()

現在のオブジェクトを表す文字列を返します。

(継承元 Object)
TryOpenExisting(String, Mutex)

既に存在する場合は、指定した名前付きミューテックスを開き操作が成功したかどうかを示す値を返します。

TryOpenExisting(String, MutexRights, Mutex)

既に存在する場合は、必要なセキュリティ アクセスを使用して指定した名前付きミューテックスを開き、操作が成功したかどうかを示す値を返します。

WaitOne()

現在の WaitHandle がシグナルを受け取るまで、現在のスレッドをブロックします。

(継承元 WaitHandle)
WaitOne(Int32)

32 ビット符号付き整数を使用して時間間隔をミリ秒単位で指定し、現在の WaitHandle がシグナルを受信するまで、現在のスレッドをブロックします。

(継承元 WaitHandle)
WaitOne(Int32, Boolean)

現在の WaitHandle がシグナルを受信するまで現在のスレッドをブロックします。時間間隔を指定するために 32 ビット符号付き整数を使用し、待機の前でも同期ドメインを終了するかどうかを指定します。

(継承元 WaitHandle)
WaitOne(TimeSpan)

TimeSpan を使用して時間間隔を指定し、現在のインスタンスがシグナルを受信するまで現在のスレッドをブロックします。

(継承元 WaitHandle)
WaitOne(TimeSpan, Boolean)

現在のインスタンスがシグナルを受信するまで現在のスレッドをブロックします。TimeSpan を使用して時間間隔を指定し、待機の前でも同期ドメインを終了するかどうかを指定します。

(継承元 WaitHandle)

明示的なインターフェイスの実装

IDisposable.Dispose()

この API は製品インフラストラクチャをサポートします。コードから直接使用するものではありません。

WaitHandle によって使用されているすべてのリソースを解放します。

(継承元 WaitHandle)

拡張メソッド

GetAccessControl(Mutex)

指定した mutex のセキュリティ記述子を返します。

SetAccessControl(Mutex, MutexSecurity)

指定したミューテックスのセキュリティ記述子を設定します。

GetSafeWaitHandle(WaitHandle)

ネイティブ オペレーティング システムの待機ハンドルのためのセーフ ハンドルを取得します。

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

ネイティブ オペレーティング システムの待機ハンドルのためのセーフ ハンドルを設定します。

適用対象

スレッド セーフ

この型はスレッド セーフです。

こちらもご覧ください