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

설명

둘 이상의 스레드가 동시에 공유 리소스에 액세스해야 하는 경우 시스템은 한 번에 하나의 스레드만 리소스를 사용하도록 하기 위한 동기화 메커니즘이 필요합니다. Mutex 는 공유 리소스에 대한 단독 액세스 권한을 하나의 스레드에만 부여하는 동기화 기본 형식입니다. 스레드가 뮤텍스를 획득하면 첫 번째 스레드가 뮤텍스를 해제할 때까지 해당 뮤텍스를 획득하려는 두 번째 스레드가 일시 중단됩니다.

중요

이 형식이 구현 하는 IDisposable 인터페이스입니다. 형식을 사용 하 여 마쳤으면 직접 또는 간접적으로의 삭제 해야 있습니다. 직접 형식의 dispose 호출 해당 Dispose 의 메서드를 try/catch 블록입니다. 삭제 하지 직접, 언어 구문 같은 사용 using (C#에서) 또는 Using (Visual Basic에서는). 자세한 내용은 "를 사용 하는 개체는 구현 IDisposable" 섹션을 참조 하세요.를 IDisposable 인터페이스 항목입니다.

메서드를 WaitHandle.WaitOne 사용하여 뮤텍스의 소유권을 요청할 수 있습니다. 호출 스레드는 다음 중 하나가 발생할 때까지 차단됩니다.

  • 뮤텍스는 소유되지 않았음을 나타내는 신호를 보냅니다. 이 경우 메서드는 WaitOne 를 반환 true하고 호출 스레드는 뮤텍스의 소유권을 가정하고 뮤텍스로 보호되는 리소스에 액세스합니다. 리소스에 대한 액세스가 완료되면 스레드는 메서드를 ReleaseMutex 호출하여 뮤텍스의 소유권을 해제해야 합니다. 예제 섹션의 첫 번째 예제에서는 이 패턴을 보여 줍니다.

  • 또는 timeout 매개 변수가 있는 메서드 millisecondsTimeout 호출에 WaitOne 지정된 제한 시간 간격이 경과했습니다. 이 경우 메서드는 WaitOne 를 반환 false하고 호출 스레드는 더 이상 뮤텍스의 소유권을 획득하지 않습니다. 이 경우 뮤텍스로 보호되는 리소스에 대한 액세스가 호출 스레드에 대해 거부되도록 코드를 구성해야 합니다. 스레드는 뮤텍스의 소유권을 획득하지 않으므로 메서드를 ReleaseMutex 호출해서는 안됩니다. 예제 섹션의 두 번째 예제에서는 이 패턴을 보여 줍니다.

클래스는 Mutex 스레드 ID를 적용하므로 뮤텍스를 획득한 스레드에서만 해제할 수 있습니다. 반면 클래스는 Semaphore 스레드 ID를 적용하지 않습니다. 뮤텍스는 애플리케이션 도메인 경계를 넘어 전달할 수도 있습니다.

뮤텍스를 소유하는 스레드는 실행을 차단하지 않고 반복 호출에서 동일한 뮤텍스를 WaitOne 요청할 수 있습니다. 그러나 스레드는 뮤텍스의 소유권을 ReleaseMutex 해제하기 위해 메서드를 동일한 횟수만큼 호출해야 합니다.

클래스는 Mutex 에서 WaitHandle상속되므로 정적 WaitHandle.WaitAllWaitHandle.WaitAny 메서드를 호출하여 보호된 리소스에 대한 액세스를 동기화할 수도 있습니다.

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

주의

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

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

뮤텍스는 이름 없는 로컬 뮤텍스와 명명된 시스템 뮤텍스의 두 가지 유형입니다. 로컬 뮤텍스는 프로세스 내에만 존재합니다. 뮤텍스를 나타내는 개체에 대한 참조가 있는 프로세스의 Mutex 모든 스레드에서 사용할 수 있습니다. 명명되지 않은 Mutex 각 개체는 별도의 로컬 뮤텍스를 나타냅니다.

명명된 시스템 뮤텍스는 운영 체제 전체에 표시되며 프로세스 활동을 동기화하는 데 사용할 수 있습니다. 이름을 허용하는 생성자를 사용하여 명명된 시스템 뮤텍스를 나타내는 개체를 만들 Mutex 수 있습니다. 운영 체제 개체를 동시에 만들거나 개체를 만들기 Mutex 전에 존재할 수 있습니다. 동일한 명명된 시스템 뮤텍스를 나타내는 여러 Mutex 개체를 만들 수 있으며 OpenExisting 메서드를 사용하여 기존 명명된 시스템 뮤텍스를 열 수 있습니다.

참고

터미널 서비스를 실행하는 서버에서 명명된 시스템 뮤텍스는 두 가지 수준의 가시성을 가질 수 있습니다. 이름이 접두 Global\사 로 시작하는 경우 모든 터미널 서버 세션에서 뮤텍스가 표시됩니다. 이름이 접두 Local\사 로 시작하는 경우 뮤텍스는 만들어진 터미널 서버 세션에서만 표시됩니다. 이 경우 동일한 이름의 별도의 뮤텍스가 서버의 다른 각 터미널 서버 세션에 있을 수 있습니다. 명명된 뮤텍스를 만들 때 접두사를 지정하지 않으면 접두사를 Local\사용합니다. 터미널 서버 세션 내에서 이름이 접두사만 다른 두 개의 뮤텍스는 별도의 뮤텍스이며 둘 다 터미널 서버 세션의 모든 프로세스에 표시됩니다. 즉, 접두사 이름과 Global\Local\ 프로세스에 상대적이지 않고 터미널 서버 세션을 기준으로 뮤텍스 이름의 scope 설명합니다.

주의

기본적으로 명명된 뮤텍스는 해당 뮤텍스를 만든 사용자로 제한되지 않습니다. 다른 사용자는 뮤텍스를 입력하고 종료하지 않음으로써 뮤텍스를 방해하는 것을 포함하여 뮤텍스를 열고 사용할 수 있습니다. Unix와 유사한 운영 체제에서 파일 시스템은 명명된 뮤텍스 구현에 사용되며, 다른 사용자는 더 중요한 방법으로 명명된 뮤텍스를 방해할 수 있습니다. Windows에서 특정 사용자에 대한 액세스를 제한하려면 생성자 오버로드를 사용하거나 MutexAcl 명명된 뮤텍스를 MutexSecurity 만들 때 을 전달할 수 있습니다. Unix와 유사한 운영 체제에서는 현재 명명된 뮤텍스에 대한 액세스를 제한할 방법이 없습니다. 신뢰할 수 없는 사용자가 코드를 실행 중일 수 있는 시스템에 대한 액세스 제한 없이 명명된 뮤텍스를 사용하지 마세요.

백슬래시(\)는 뮤텍스 이름의 예약 문자입니다. 터미널 서버 세션에서 뮤텍스 사용에 대한 메모에 지정된 경우를 제외하고 뮤텍스 이름에 백슬래시(\)를 사용하지 마세요. 그렇지 않으면 뮤텍스의 이름이 기존 파일을 나타내더라도 DirectoryNotFoundException이 throw될 수 있습니다.

생성자

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)

부호 있는 32비트 정수로 시간 간격을 지정하고 대기 전에 동기화 도메인을 끝낼지 여부를 지정하여 현재 WaitHandle이 신호를 받을 때까지 현재 스레드를 차단합니다.

(다음에서 상속됨 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)

네이티브 운영 체제 대기 핸들에 대한 안전한 핸들을 설정합니다.

적용 대상

스레드 보안

이 형식은 스레드로부터 안전합니다.

추가 정보