英語で読む

次の方法で共有


Mutex.ReleaseMutex メソッド

定義

Mutex を一度解放します。

public void ReleaseMutex ();

例外

呼び出しスレッドに独自のミューテックスがありません。

現在のインスタンスは既に破棄されています。

次の例は、ローカル Mutex オブジェクトを使用して保護されたリソースへのアクセスを同期する方法を示しています。 ミューテックスを作成するスレッドは、最初にそれを所有していません。 メソッドは 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.
 
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();
    }
}

注釈

スレッドがミューテックスを取得するたびに (たとえば、その WaitOne メソッドを呼び出すことによって)、その後 を呼び出 ReleaseMutex してミューテックスの所有権を放棄し、ミューテックスの所有権を取得しようとしている他のスレッドのブロックを解除する必要があります。 ミューテックスの所有権の取得が失敗した場合 (たとえば、 または timeout パラメーターを使用millisecondsTimeoutしたメソッドのWaitOne呼び出しが、要求がタイムアウトしたために が返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

ミューテックスを所有するスレッドは、実行をブロックすることなく、繰り返し待機関数呼び出しで同じミューテックスを指定できます。 呼び出しの数は、共通言語ランタイムによって保持されます。 ミューテックスの所有権を解放するには、スレッドが同じ回数を呼び出す ReleaseMutex 必要があります。

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

注意事項

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

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

適用対象

製品 バージョン
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.6, 2.0, 2.1
UWP 10.0

こちらもご覧ください