잠금, 뮤텍스, 세마포… 차이점은 무엇입니까?


답변:


534

잠금은 하나의 스레드 만 잠긴 파트에 들어갈 수있게하며 다른 프로세스와 공유되지 않습니다.

뮤텍스는 잠금과 동일하지만 시스템 전체 (여러 프로세스가 공유) 일 수 있습니다.

세마포어는 뮤텍스와 같은 작업을 수행하지만, 입력 스레드의 X 번호,이, IO를 CPU의 수를 제한하거나 동시에 실행 집약적 인 작업을 숫양 예를 들어 사용할 수 있습니다.

뮤텍스와 세마포어의 차이점에 대한 자세한 내용은 여기를 참조하십시오 .

또한 읽기 / 쓰기 잠금 기능을 사용하여 주어진 시간에 무제한의 독자 또는 1 명의 작성자를 허용합니다.


2
@mertinan 나는 그것에 대해 들어 본 적이 없다. 그러나 이것은 위키피디아가 "인덱스와 같은 시스템 데이터 구조에 대한 래치 (데이터베이스), (상대적으로 수명이 짧은) 잠금"이라고 말한다
Peter

2
모니터는 특정 상태 (예 : 잠금이 해제 된 경우), "모니터"를 기다릴 수 있습니다.
Dzmitry Lazerka

25
세마포어는 뮤텍스와 동일하지 않습니다. 그것들은 매우 다르게 사용되며 다른 속성 (즉 소유권에 관한)도 가지고 있습니다. 자세한 내용은 barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore 를 참조하십시오.
nanoquack

3
@nanoquack은 오해의 소지가 있거나 부정확하다고 생각되면 자유롭게 답변을 편집하십시오.
피터

3
뮤텍스와 세마포어를보다 명확하게 구분하기 위해 nanoquack의 링크에서 핵심 단락은 " 세마포어를 올바르게 사용하는 것은 한 작업에서 다른 작업으로 신호를 보내는 것입니다. 공유 리소스를 사용하여 보호하는 작업 반면에 세마포어를 사용하는 작업은 신호 또는 대기 중 둘 다가 아니라 신호 또는 대기 중입니다. "
ToolmakerSteve

117

이 단어들에 관해 많은 오해가 있습니다.

이것은 이전 게시물 ( https://stackoverflow.com/a/24582076/3163691 ) 에서 가져온 것입니다.

1) Critical Section = 하나의 프로세스 내 에서 다른 많은 스레드 로부터 하나의 활성 스레드 를 실행하는 데 사용되는 사용자 개체 . 선택되지 않은 다른 스레드 (@이 객체를 획득)는 휴면 상태가 됩니다.

[프로세스 기능이없고 매우 원시적 인 개체].

2) Mutex Semaphore (일명 Mutex) = 여러 프로세스 중에서 다른 많은 것 중 하나의 활성 스레드 를 실행하는 데 사용되는 커널 객체 . 선택되지 않은 다른 스레드 (@이 객체를 획득)는 휴면 상태가 됩니다. 이 객체는 스레드 소유권, 스레드 종료 알림, 재귀 (동일한 스레드에서 여러 개의 '취득'호출) 및 '우선 순위 반전 방지'를 지원합니다.

[사용하기 매우 안전한 프로세스 간 기능, 일종의 '고수준'동기화 개체].

3) 카운팅 세마포어 (일명 세마포어) = 많은 다른 스레드 로부터 활성 스레드 그룹을 실행하는 데 사용되는 커널 객체 . 선택되지 않은 다른 스레드 (@이 객체를 획득)는 휴면 상태가 됩니다.

[프로세스 기능은 스레드 종료 알림, 재귀?, '우선 순위 반전 방지'등의 '뮤텍스'속성이 없기 때문에 사용하기에 안전하지 않습니다.]

4) 이제 '스핀 록'에 대해 이야기하면서 먼저 몇 가지 정의를 정의하십시오.

Critical Region = 2 개 이상의 프로세스가 공유하는 메모리 영역.

Lock = 값이 '핵심 영역'으로의 진입을 허용하거나 거부하는 변수입니다. (이것은 간단한 '부울 플래그'로 구현 될 수 있습니다).

통화 중 대기 = 일부 값이 나타날 때까지 변수를 계속 테스트합니다.

드디어:

Spin-lock (일명 Spinlock) = 통화 중 대기 를 사용 하는 잠금 . (다음은 취득 단계 로크 가 이루어진다 XCHG 또는 유사한 원자 조작 ).

[스레드 슬리핑이 없으며 대부분 커널 레벨에서만 사용됩니다. 사용자 수준 코드에 비효율적입니다].

마지막으로, 확실하지는 않지만 위의 첫 번째 3 개의 동기화 객체 (# 1, # 2 및 # 3)가 구현의 일부로이 간단한 짐승 (# 4)을 사용한다는 큰 벅을 걸 수 있습니다.

좋은 하루 되세요!.

참고 문헌 :

캐롤라인 야오 (CMP Books)와의 Qing Li의 임베디드 시스템에 대한 실시간 개념.

Andrew Tanenbaum (Pearson Education International)의 현대 운영 체제 (3 차)

-Jeffrey Richter (Microsoft Programming Series)의 Microsoft Windows 용 프로그래밍 응용 프로그램 (4 번째).

또한 https://stackoverflow.com/a/24586803/3163691 을 살펴볼 수 있습니다.


1
사실 중요한 부분은 없습니다 , 따라서 더 가볍고 프로세스간에 동기화 할 수없는 커널 객체.
Vladislavs Burakovs

2
@ Vladislavs Burakovs : 당신 말이 맞아요! 내 편집을 용서하십시오. 일관성을 위해 수정하겠습니다.
fante September

nanoquack이 다른 곳에서 언급했듯이 뮤텍스와 세마포어를 명확하게 구분하려면 barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore를 참조하십시오 . 주요 단락은 " 세마포어의 올바른 사용법은 한 작업에서 신호를 보내는 것입니다. 뮤텍스는 공유 리소스를 사용하는 각 작업에 따라 항상 순서대로 취출 및 릴리스되어야하지만, 세마포어를 사용하는 작업은 신호 또는 대기 중 둘 다가 아니라 "
ToolmakerSteve

다른 잠금 메커니즘은 [비효율적 인] spinlock을 기반으로 추측한다. AFAIK에는 일부 원자 작업 과 수면 대기열 만 필요합니다 . 커널 내부 에서 spinlock 필요한 경우에도 최신 솔루션은 Wikipedia-Spinlock-Alternatives- "에 설명 된대로 영향을 최소화합니다 ."adaptive mutex "라는 하이브리드 접근 방식을 사용하십시오. A는 스레드를 현재 실행하지만, 잠을 스레드가 현재 실행되고 있지 않은 경우 (후자는 항상 단일 프로세서 시스템의 경우입니다.). "
ToolmakerSteve

@ToolmakerSteve, 스레드 ID를 '슬립 큐'에 '삽입'할 때 '충돌'문제에 대해 '스핀 록'이없는 '솔루션'을 제공해야합니다. 어쨌든 Wikipedia 텍스트는 spinlock이 구현에 사용된다고 결론지었습니다 !!!.
fante February

27

대부분의 문제는 (i) 단지 잠금, (ii) 단지 세마포어, 또는 (iii) 둘의 조합을 사용하여 해결할 수 있습니다! 아시다시피, 경쟁 조건을 방지하고 , 운영 acquire()/ release()운영하고, 0 개 이상의 스레드가 차단 / 의심되는 원인이됩니다. 실제로 중요한 차이점은 잠금 및 잠금 해제 방법 에만 있습니다 .

  • 로크 (또는 뮤텍스 ) 두 상태 (0 또는 1)을 갖는다. 잠금을 해제 하거나 잠글 수 있습니다 . 한 번에 하나의 스레드 만 중요한 섹션에 들어가도록하는 데 자주 사용됩니다.
  • 세마포어가 많은 상태가 (0, 1, 2, ...). 그것은 수 로크 (상태 0) 또는 잠금 해제 (3, 2, 1 상태, ...). 일부 자원의 단위 수가 특정 값에 도달하지 않았거나 그 값까지 카운트하거나 그 값까지 카운트하여 하나의 스레드 만 중요한 섹션에 정확하게 들어가도록하기 위해 하나 이상의 세마포어가 함께 사용되는 경우가 종종 있습니다. ).

두 잠금 / 세마포 모두에 acquire()대해 기본 요소가 상태 0 인 동안 호출하려고 하면 호출 스레드가 일시 중단됩니다. 잠금의 경우-잠금을 확보하려는 시도가 상태 1에 있습니다. 세마포어의 경우 {1, 2, 3, ...} 상태에서 잠금을 획득하려는 시도가 성공했습니다.

상태가 0 인 잠금의 경우 , 이전에 호출했던 동일한 스레드가 acquire()이제 release를 호출하면 릴리스가 성공한 것입니다. 경우 다른 스레드가이 시도 - 그것은 일 (무시 보통 시도 또는 오류가 발생합니다) 무엇으로 구현 / 라이브러리까지입니다. 상태 0의 세마포어의 경우 모든 스레드가 해제를 호출 할 수 있으며 이전에 사용 된 스레드가 세마포어를 상태 0에 놓기 위해 획득 한 스레드에 관계없이 성공합니다.

앞의 논의에서 잠금에는 소유자 (방출을 호출 할 수있는 유일한 스레드가 소유자 임) 라는 개념이 있지만 세마포어에는 소유자가 없습니다 (모든 스레드가 세마포어에서 릴리스를 호출 할 수 있음).


혼동을 일으키는 원인은 실제로 는 이러한 높은 수준의 정의에 많은 변형 이 있다는 것입니다.

고려해야 할 중요한 변형 :

  • 뭐라고를한다 acquire()/ release()호출? - [다름 대규모 ]
  • 잠금 / 세마포어가 "대기열"또는 "세트"를 사용하여 대기중인 스레드를 기억합니까?
  • 잠금 / 세마포어를 다른 프로세스의 스레드와 공유 할 수 있습니까?
  • 자물쇠가 "재진입"입니까? -[보통 예].
  • 자물쇠가 "차단 / 비 차단"입니까? -[일반적으로 비 차단은 차단 잠금 (일명 스핀 잠금)으로 인해 통화 중 대기]로 사용됩니다.
  • 작업이 "원자"인지 어떻게 확인합니까?

이것은 책 / 강사 / 언어 / 도서관 / 환경에 따라 다릅니다.
다음은 일부 언어가 이러한 세부 사항에 응답하는 방법에 대한 빠른 둘러보기입니다.


C, C ++ ( pthreads )

  • 뮤텍스 를 통해 구현된다 pthread_mutex_t. 기본적으로 다른 프로세스와 공유 할 수 PTHREAD_PROCESS_PRIVATE없지만 mutex에는 pshared 라는 속성이 있습니다 . 설정되면 뮤텍스가 프로세스간에 공유됩니다 ( PTHREAD_PROCESS_SHARED).
  • 잠금 뮤텍스와 같은 것입니다.
  • 세마포어 를 통해 구현된다 sem_t. 뮤텍스와 유사하게, 세마포어는 많은 프로세스의 threasd간에 공유되거나 하나의 단일 프로세스 스레드에 대해 비공개로 유지 될 수 있습니다. 이는에 제공된 pshared 인수 에 따라 다릅니다 sem_init.

파이썬 ( threading.py )

  • 잠금 ( threading.RLock) 대부분 C / C ++과 동일 pthread_mutex_t들. 둘 다 재진입 입니다. 이는 잠금 된 동일한 스레드에 의해서만 잠금 해제 될 수 있음을 의미합니다. 이 경우입니다 sem_t세마포어, threading.Semaphore세마포어와 theading.Lock잠금 장치가 재진입하지 - 그것은의 경우에 대한 모든 스레드가 세마포어 아래 / 잠금을 해제 수행 할 수 있습니다.
  • 뮤텍스 잠금 (용어 파이썬 자주 사용되지 않음)과 동일하다.
  • 세마포어 ( threading.Semaphore) 대부분 동일하다 sem_t. 에 있지만 sem_t, 스레드 ID의 큐는이 잠겨있는 동안을 고정 할 때 스레드가 차단되었다 순서를 기억하는 데 사용됩니다. 스레드가 세마포어를 잠금 해제 하면 큐 의 첫 번째 스레드 (있는 경우)가 새 소유자로 선택됩니다. 스레드 ID가 큐에서 제거되고 세마포어가 다시 잠 깁니다. 그러나을 threading.Semaphore사용하면 대기열 대신 세트가 사용되므로 스레드가 차단 된 순서는 저장되지 않습니다 . 세트의 모든 스레드가 다음 소유자로 선택 될 수 있습니다.

자바 ( java.util.concurrent )

  • 잠금 ( java.util.concurrent.ReentrantLock) 대부분 C / C ++와 동일한 pthread_mutex_t의, 파이썬의 threading.RLock그것도 재진입 잠금을 구현하는 것이있다. JVM이 중개자 역할을하기 때문에 Java에서 프로세스 간 잠금 공유가 더 어렵습니다. 스레드가 잠금을 잠금 해제하려고 시도하면 소유하지 않은 것 IllegalMonitorStateException입니다.
  • 뮤텍스 잠금 (용어가 자바에서 자주 사용되지 않음)과 동일합니다.
  • 세마포어 ( java.util.concurrent.Semaphore) 대부분과 동일 sem_t하고 threading.Semaphore. Java 세마포어의 생성자 는 대기중인 스레드를 저장하기 위해 세트 (false) 또는 큐 (true)를 사용할지 여부를 제어 하는 공정성 부울 매개 변수를 승인 합니다.

이론적으로 세마포어는 종종 논의되지만 실제로 세마포어는 그다지 많이 사용되지 않습니다. 세마포어는 하나의 정수 상태 만 유지 하므로 종종 융통성이 없어서 한 번에 많은 것이 필요하므로 코드 이해가 어려워집니다. 또한 어떤 스레드가 세마포어를 해제 할 수 있다는 사실 은 때때로 바람직하지 않습니다. "조건 변수"및 "모니터"와 같은 더 많은 객체 지향 / 고급 동기화 기본 요소 / 추상화가 대신 사용됩니다.


22

John Kopplin의 멀티 스레딩 자습서 를 살펴보십시오 .

스레드 간 동기화 섹션 에서 이벤트, 잠금, 뮤텍스, 세마포어, 대기 타이머 간의 차이점을 설명합니다.

뮤텍스는 공유 자원에 대한 상호 배타적 인 액세스를 조정하는 스레드를 가능하게 한 번에 하나의 스레드가 소유 할 수있다

중요 섹션 개체 는 단일 프로세스의 스레드에서만 중요 섹션 개체를 사용할 수 있다는 점을 제외하고 뮤텍스 개체와 유사한 동기화를 제공합니다.

뮤텍스크리티컬 섹션의 또 다른 차이점 은 현재 크리티컬 섹션 객체가 다른 스레드에 의해 소유 된 EnterCriticalSection()경우 소유권을 무기한으로 기다리는 반면 WaitForSingleObject()뮤텍스와 함께 사용되는 경우 시간 초과를 지정할 수 있다는 것입니다

세마포어 동시에 공유 자원에 액세스하는 스레드의 수를 제한하는, 제로 카운트 사이의 약간의 최대 값을 유지한다.


15

나는 그것을 예제로 다루려고 노력할 것이다.

잠금 : 사용하는 한 가지 예는 lock항목 (고유 키가 있어야 함)이 추가 된 공유 사전입니다.
잠금은 한 스레드가 사전에있는 항목을 검사하는 코드 메커니즘에 들어 가지 않고 다른 스레드 (중요 섹션에 있음)가 이미이 검사를 통과하여 항목을 추가하고 있는지 확인합니다. 다른 스레드가 잠긴 코드를 입력하려고하면 객체가 해제 될 때까지 기다립니다 (차단됨).

private static readonly Object obj = new Object();

lock (obj) //after object is locked no thread can come in and insert item into dictionary on a different thread right before other thread passed the check...
{
    if (!sharedDict.ContainsKey(key))
    {
        sharedDict.Add(item);
    }
}

세마포어 : 연결 풀이 있다고 가정하면 단일 스레드가 세마포어가 연결될 때까지 대기하여 풀에 하나의 요소를 예약 할 수 있습니다. 그런 다음 연결을 사용하고 작업이 완료되면 세마포어를 해제하여 연결을 해제합니다.

내가 좋아하는 코드 예제는 @Patric이 제공 한 경비원 중 하나입니다 .

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace TheNightclub
{
    public class Program
    {
        public static Semaphore Bouncer { get; set; }

        public static void Main(string[] args)
        {
            // Create the semaphore with 3 slots, where 3 are available.
            Bouncer = new Semaphore(3, 3);

            // Open the nightclub.
            OpenNightclub();
        }

        public static void OpenNightclub()
        {
            for (int i = 1; i <= 50; i++)
            {
                // Let each guest enter on an own thread.
                Thread thread = new Thread(new ParameterizedThreadStart(Guest));
                thread.Start(i);
            }
        }

        public static void Guest(object args)
        {
            // Wait to enter the nightclub (a semaphore to be released).
            Console.WriteLine("Guest {0} is waiting to entering nightclub.", args);
            Bouncer.WaitOne();          

            // Do some dancing.
            Console.WriteLine("Guest {0} is doing some dancing.", args);
            Thread.Sleep(500);

            // Let one guest out (release one semaphore).
            Console.WriteLine("Guest {0} is leaving the nightclub.", args);
            Bouncer.Release(1);
        }
    }
}

뮤텍스 (Mutex) 그것은 거의 Semaphore(1,1)전 세계적으로 많이 사용됩니다 lock. Mutex전역 적으로 액세스 가능한 목록에서 노드를 삭제할 때 전역을 사용 합니다 (마지막으로 노드를 삭제하는 동안 다른 스레드가 수행하려는 작업). 당신이 취득하면 Mutex다른 스레드의 시도가 동일하게 획득 할 경우 Mutex이를 획득 한 같은 스레드까지 잠을 넣어지게된다 Mutex출시를.

글로벌 뮤텍스를 만드는 좋은 예는 @deepee입니다.

class SingleGlobalInstance : IDisposable
{
    public bool hasHandle = false;
    Mutex mutex;

    private void InitMutex()
    {
        string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
        string mutexId = string.Format("Global\\{{{0}}}", appGuid);
        mutex = new Mutex(false, mutexId);

        var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
        var securitySettings = new MutexSecurity();
        securitySettings.AddAccessRule(allowEveryoneRule);
        mutex.SetAccessControl(securitySettings);
    }

    public SingleGlobalInstance(int timeOut)
    {
        InitMutex();
        try
        {
            if(timeOut < 0)
                hasHandle = mutex.WaitOne(Timeout.Infinite, false);
            else
                hasHandle = mutex.WaitOne(timeOut, false);

            if (hasHandle == false)
                throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
        }
        catch (AbandonedMutexException)
        {
            hasHandle = true;
        }
    }


    public void Dispose()
    {
        if (mutex != null)
        {
            if (hasHandle)
                mutex.ReleaseMutex();
            mutex.Dispose();
        }
    }
}

다음과 같이 사용하십시오.

using (new SingleGlobalInstance(1000)) //1000ms timeout on global lock
{
    //Only 1 of these runs at a time
    GlobalNodeList.Remove(node)
}

시간이 절약되기를 바랍니다.


8

Wikipedia에는 세마포어와 뮤텍스차이점 에 대한 훌륭한 섹션이 있습니다 .

뮤텍스는 본질적으로 이진 세마포어와 동일하며 때로는 동일한 기본 구현을 사용합니다. 그들 사이의 차이점은 다음과 같습니다.

뮤텍스에는 소유자라는 개념이 있는데, 뮤텍스를 잠그는 프로세스입니다. 뮤텍스를 잠근 프로세스 만 잠금을 해제 할 수 있습니다. 반대로 세마포어에는 소유자 개념이 없습니다. 모든 프로세스는 세마포어를 잠금 해제 할 수 있습니다.

세마포어와 달리 뮤텍스는 우선 순위 반전 안전을 제공합니다. 뮤텍스는 현재 소유자를 알고 있기 때문에 우선 순위가 높은 작업이 뮤텍스에서 대기하기 시작할 때마다 소유자의 우선 순위를 높이는 것이 가능합니다.

뮤텍스는 뮤텍스를 유지하는 프로세스를 실수로 삭제할 수없는 삭제 안전성을 제공합니다. 세마포어는 이것을 제공하지 않습니다.


5

내 이해는 뮤텍스가 단일 프로세스 내에서만 사용되지만 많은 스레드에서 사용되는 반면 세마포어는 여러 프로세스 및 해당 스레드 세트에서 사용될 수 있다는 것입니다.

또한 뮤텍스는 이진 (잠금 또는 잠금 해제) 인 반면, 세마포어는 계산 개념 또는 둘 이상의 잠금 및 잠금 해제 요청 큐를 갖습니다.

누군가 내 설명을 확인할 수 있습니까? 저는 Linux, 특히 커널 2.6.32를 사용하는 RHEL (Red Hat Enterprise Linux) 버전 6의 맥락에서 말하고 있습니다.


3
이제 이것은 운영 체제마다 다를 수 있지만 Windows에서는 최소한 .net Mutex 객체로 여러 프로세스에서 Mutex를 사용할 수 있습니다.
Peter

2
stackoverflow.com/questions/9389730/… "같은 프로세스 또는 다른 프로세스 내의 스레드는 뮤텍스를 공유 할 수 있습니다." 따라서 뮤텍스가 프로세스 특정 적이 어서는 안됩니다.
피터

3

Linux 변형에서 C 프로그래밍을 기본 사례로 사용합니다.

자물쇠:

• 일반적으로 잠금 또는 잠금 해제 작업 중 매우 간단한 구성 바이너리

스레드 소유권, 우선 순위, 시퀀싱 등의 개념이 없습니다.

• 일반적으로 스레드가 잠금 가용성을 지속적으로 확인하는 스핀 잠금입니다.

• 일반적으로 테스트 및 설정, 비교 및 ​​스왑, 페치 및 추가 등과 같은 원 자성 작업에 의존합니다.

• 일반적으로 원자 작동을위한 하드웨어 지원이 필요합니다.

파일 잠금 :

• 일반적으로 여러 프로세스를 통해 파일에 대한 액세스를 조정하는 데 사용됩니다.

• 여러 프로세스가 읽기 잠금을 유지할 수 있지만 단일 프로세스가 쓰기 잠금을 유지하면 다른 프로세스가 읽기 또는 쓰기 잠금을 획득 할 수 없습니다.

• 예 : flock, fcntl 등

뮤텍스 :

• Mutex 함수 호출은 일반적으로 커널 공간에서 작동하며 시스템 호출이 발생합니다.

• 소유권 개념을 사용합니다. 현재 뮤텍스를 보유하고있는 스레드 만이 잠금을 해제 할 수 있습니다.

• Mutex는 재귀 적이 지 않습니다 (예외 : PTHREAD_MUTEX_RECURSIVE).

• 일반적으로 조건 변수와 연관하여 사용되며 pthread_cond_signal, pthread_cond_wait 등의 인수로 전달됩니다.

• 일부 UNIX 시스템에서는 여러 시스템에서 mutex를 사용할 수 있지만 일부 시스템에서는 mutex를 사용할 수 없습니다.

신호기:

• 커널 유지 정수로 값이 0 미만으로 떨어지지 않습니다.

• 프로세스를 동기화하는 데 사용할 수 있습니다.

• 세마포어 값은 1보다 큰 값으로 설정 될 수 있습니다.이 경우 값은 일반적으로 사용 가능한 리소스 수를 나타냅니다.

• 값이 1과 0으로 제한된 세마포어는 이진 세마포어라고합니다.


0

Supporting ownership, maximum number of processes share lock및은 maximum number of allowed processes/threads in critical section일반적인 이름 동시 오브젝트의 이름 / 타입을 결정하는 세 가지 주요 인자이다 lock. 이러한 요소의 값은 2 진 (2 가지 상태)이므로 3 * 8 진리와 같은 표로 요약 할 수 있습니다.

  • X (소유권 지원?) : no (0) / yes (1)
  • Y (# 공유 프로세스) :> 1 (∞) / 1
  • Z (CA의 # 프로세스 / 스레드) :> 1 (∞) / 1

  X   Y   Z          Name
 --- --- --- ------------------------
  0   ∞   ∞   Semaphore              
  0   ∞   1   Binary Semaphore       
  0   1   ∞   SemaphoreSlim          
  0   1   1   Binary SemaphoreSlim(?)
  1   ∞   ∞   Recursive-Mutex(?)     
  1   ∞   1   Mutex                  
  1   1   ∞   N/A(?)                 
  1   1   1   Lock/Monitor           

이 테이블을 자유롭게 편집하거나 확장하십시오. 편집 할 수 있도록 ascii 테이블로 게시했습니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.