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 番目のスレッドは、最初のスレッドがミューテックスを解放するまで中断されます。

Important

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

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

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

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

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

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

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

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

Caution

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

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

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

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

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

Caution

既定では、名前付きミューテックスは、それを作成したユーザーに制限されません。 他のユーザーは、ミューテックスを開いて使用できる場合があります。ミューテックスに入ってミューテックスを終了しないことによってミューテックスに干渉する場合などです。 Unix に似たオペレーティング システムでは、ファイル システムは名前付きミューテックスの実装で使用され、他のユーザーは、より重要な方法で名前付きミューテックスを干渉できる可能性があります。 Windowsでは、特定のユーザーへのアクセスを制限するために、コンストラクター オーバーロードまたは MutexAcl を使用し、名前付きミューテックスの作成時に MutexSecurity を渡すことができます。 Unix に似たオペレーティング システムでは、現在、名前付きミューテックスへのアクセスを制限する方法はありません。 信頼されていないユーザーがコードを実行している可能性があるシステムでは、アクセス制限なしで名前付きミューテックスを使用しないでください。

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

コンストラクター

名前 説明
Mutex()

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

Mutex(Boolean, String, Boolean, MutexSecurity)

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

Mutex(Boolean, String, Boolean)

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

Mutex(Boolean, String, NamedWaitHandleOptions, Boolean)

呼び出し元のスレッドがミューテックスの初期所有権を持つ必要があるかどうかを示すブール値、ミューテックスの名前である文字列、ユーザー スコープとセッション スコープのアクセスを設定するオプション、メソッドが戻るときに呼び出し元スレッドにミューテックスの初期所有権が付与されたかどうかを示すブール値を使用して、 Mutex クラスの新しいインスタンスを初期化します。

Mutex(Boolean, String, NamedWaitHandleOptions)

呼び出し元のスレッドがミューテックスの初期所有権を持つ必要があるかどうかを示すブール値、ミューテックスの名前である文字列、およびユーザー スコープとセッション スコープのアクセスを設定するためのオプションを使用して、 Mutex クラスの新しいインスタンスを初期化します。

Mutex(Boolean, String)

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

Mutex(Boolean)

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

Mutex(String, NamedWaitHandleOptions)

ミューテックスの名前と、ユーザー スコープとセッション スコープのアクセスを設定するためのオプションである文字列を使用して、 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, MutexRights)

指定した名前付きミューテックスが既に存在する場合は、目的のセキュリティ アクセスを使用して開きます。

OpenExisting(String, NamedWaitHandleOptions)

指定した名前付きミューテックスが既に存在する場合は、それを開きます。 オプションが現在のユーザーのみに設定されている場合、オブジェクトのアクセス制御は呼び出し元のユーザーに対して検証されます。

OpenExisting(String)

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

ReleaseMutex()

Mutexを 1 回解放します。

SetAccessControl(MutexSecurity)

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

ToString()

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

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

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

TryOpenExisting(String, MutexRights, Mutex)

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

TryOpenExisting(String, NamedWaitHandleOptions, Mutex)

指定した名前付きミューテックスが既に存在する場合は開き、操作が成功したかどうかを示す値を返します。 オプションが現在のユーザーのみに設定されている場合、オブジェクトのアクセス制御は呼び出し元のユーザーに対して検証されます。

WaitOne()

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

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

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

(継承元 WaitHandle)
WaitOne(Int32)

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

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

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

(継承元 WaitHandle)
WaitOne(TimeSpan)

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

(継承元 WaitHandle)

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

名前 説明
IDisposable.Dispose()

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

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

(継承元 WaitHandle)

拡張メソッド

名前 説明
GetAccessControl(Mutex)

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

GetSafeWaitHandle(WaitHandle)

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

SetAccessControl(Mutex, MutexSecurity)

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

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

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

適用対象

スレッド セーフ

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

こちらもご覧ください