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 使用して、ミューテックスの所有権を要求できます。 呼び出し元のスレッドは、次のいずれかが発生するまでブロックします。

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

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

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

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

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

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

注意事項

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

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

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

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

Note

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

注意事項

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

円記号 (\) はミューテックス名の予約文字です。 ターミナル サーバー セッションでのミューテックスの使用に関するメモで指定されている場合を除き、ミューテックス名に円記号 (\) を使用しないでください。 使用した場合、ミューテックスの名前が既存のファイルを表すとしても、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)

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

適用対象

スレッド セーフ

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

こちらもご覧ください