다음을 통해 공유


Mutex.ReleaseMutex 메서드

정의

Mutex을(를) 한 번 해제합니다.

public:
 void ReleaseMutex();
public void ReleaseMutex ();
member this.ReleaseMutex : unit -> unit
Public Sub 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 namespace System;
using namespace System::Threading;
const int numIterations = 1;
const int numThreads = 3;
ref class Test
{
public:

   // Create a new Mutex. The creating thread does not own the
   // Mutex.
   static Mutex^ mut = gcnew Mutex;
   static void MyThreadProc()
   {
      for ( int i = 0; i < numIterations; i++ )
      {
         UseResource();

      }
   }


private:

   // This method represents a resource that must be synchronized
   // so that only one thread at a time can enter.
   static void UseResource()
   {
      
      //Wait until it is OK to enter.
      mut->WaitOne();
      Console::WriteLine( "{0} has entered protected the area", Thread::CurrentThread->Name );
      
      // Place code to access non-reentrant resources here.
      // Simulate some work.
      Thread::Sleep( 500 );
      Console::WriteLine( "{0} is leaving protected the area\r\n", Thread::CurrentThread->Name );
      
      // Release the Mutex.
      mut->ReleaseMutex();
   }

};

int main()
{
   
   // Create the threads that will use the protected resource.
   for ( int i = 0; i < numThreads; i++ )
   {
      Thread^ myThread = gcnew Thread( gcnew ThreadStart( Test::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.
}
// 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();
    }
}
' 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.
 
Imports System.Threading

Class Test
    ' Create a new Mutex. The creating thread does not own the
    ' Mutex.
    Private Shared mut As New Mutex()
    Private Const numIterations As Integer = 1
    Private Const numThreads As Integer = 3

    <MTAThread> _
    Shared Sub Main()
        ' Create the threads that will use the protected resource.
        Dim i As Integer
        For i = 1 To numThreads
            Dim myThread As New Thread(AddressOf MyThreadProc)
            myThread.Name = [String].Format("Thread{0}", i)
            myThread.Start()
        Next i

        ' The main thread exits, but the application continues to
        ' run until all foreground threads have exited.

    End Sub

    Private Shared Sub MyThreadProc()
        Dim i As Integer
        For i = 1 To numIterations
            UseResource()
        Next i
    End Sub

    ' This method represents a resource that must be synchronized
    ' so that only one thread at a time can enter.
    Private Shared Sub UseResource()
        ' Wait until it is safe to enter.
        mut.WaitOne()

        Console.WriteLine("{0} has entered protected area", _
            Thread.CurrentThread.Name)

        ' Place code to access non-reentrant resources here.

        ' Simulate some work
        Thread.Sleep(500)

        Console.WriteLine("{0} is leaving protected area" & vbCrLf, _
            Thread.CurrentThread.Name)

        ' Release Mutex.
        mut.ReleaseMutex()
    End Sub
End Class

설명

스레드가 뮤텍스를 획득할 때마다(예: 메서드 WaitOne 를 호출하여) 이후에 뮤텍스의 소유권을 포기하고 뮤텍스의 소유권을 얻으려는 다른 스레드의 차단을 해제하도록 호출 ReleaseMutex 해야 합니다. 뮤텍스의 소유권을 가져오기 위한 시도가 실패하는 경우(예: 요청 시간이 초과되어 WaitOne 매개 변수 false 를 사용하여 메서드 millisecondsTimeout timeout 를 호출하는 경우) 스레드는 호출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

뮤텍스를 소유하는 스레드는 실행을 차단하지 않고 반복 대기 함수 호출에서 동일한 뮤텍스를 지정할 수 있습니다. 호출 수는 공용 언어 런타임에 의해 유지됩니다. 스레드는 뮤텍스의 소유권을 해제하기 위해 동일한 횟수를 호출 ReleaseMutex 해야 합니다.

뮤텍스를 소유하는 동안 스레드가 종료되면 뮤텍스는 중단되었다고 합니다. 뮤텍스 상태가 신호로 설정되고 다음 대기 스레드가 소유권을 가져옵니다. 아무도 뮤텍스를 소유하지 않으면 뮤텍스의 상태가 신호됩니다. .NET Framework AbandonedMutexException 버전 2.0부터 뮤텍스를 획득하는 다음 스레드에서 throw됩니다. .NET Framework 버전 2.0 이전에는 예외가 throw되지 않았습니다.

주의

중단된 뮤텍스는 코드에서 심각한 오류를 나타내는 경우가 많습니다. 뮤텍스를 해제하지 않고 스레드가 종료되면 뮤텍스로 보호되는 데이터 구조가 일관되지 않을 수 있습니다. 뮤텍스의 소유권을 요청하는 다음 스레드는 이 예외를 처리하고 데이터 구조의 무결성을 확인할 수 있는 경우 계속 진행할 수 있습니다.

시스템 차원 뮤텍스의 경우 중단된 뮤텍스는 애플리케이션이 갑자기 종료되었음을 나타낼 수 있습니다(예: Windows 작업 관리자를 사용하여).

적용 대상

추가 정보