언제 뮤텍스를 사용해야하고 언제 세마포어를 사용해야합니까?


답변:


92

다음은 언제 무엇을 사용해야하는지 기억하는 방법입니다.

세마포어 : 다른 스레드가 깨어나도록 지시 할 때까지 (스레드) 잠자기를 원할 때 세마포어를 사용합니다. 세마포어 '다운'은 한 스레드 (생산자)에서 발생하고 세마포어 '업'(동일한 세마포어)은 다른 스레드 (소비자)에서 발생합니다. 소비자 스레드는 버퍼 슬롯이 비어있는시기를 알 수 있습니다.

뮤텍스 : (스레드) 다른 스레드에서 동시에 실행해서는 안되는 코드를 실행하려는 경우 뮤텍스를 사용합니다. 뮤텍스 '다운'은 한 스레드에서 발생하고 뮤텍스 '업' 나중에 동일한 스레드에서 발생 해야합니다 . 예 : 글로벌 연결 목록에서 노드를 삭제하는 경우 노드를 삭제하는 동안 다른 스레드가 포인터를 사용하는 것을 원하지 않습니다. 뮤텍스를 획득하고 노드 삭제 중일 때 다른 스레드가 동일한 뮤텍스를 획득하려고 시도하면 뮤텍스를 해제 할 때까지 휴면 상태가됩니다.

Spinlock : 실제로 뮤텍스를 사용하고 싶지만 스레드가 절전 모드로 전환되지 않을 때 스핀 락 을 사용합니다. 예 : OS 커널 내의 인터럽트 핸들러는 절대 휴면 상태가 아니어야합니다. 그렇다면 시스템이 정지 / 충돌합니다. 인터럽트 처리기에서 전역 적으로 공유되는 연결 목록에 노드를 삽입해야하는 경우 스핀 락을 획득합니다-노드 삽입-스핀 락 해제.


1
추가 할 : 세마포어와 뮤텍스는 동기화를 제공하는 두 가지 방법입니다. 세마포어는 시그널링 (예 : 생산자 및 소비자 문제 시나리오)과 더 관련 될 수 있고 뮤텍스는 한 번에 하나씩 액세스를 허용하는 것과 더 관련 될 수 있습니다 (공유 리소스에 액세스하기위한 여러 요청, 한 번에 하나만 부여됨). [좋은 기사 : geeksforgeeks.org/mutex-vs-semaphore/]
parasrish

57

뮤텍스는 세마포어 와 유사 하지만 한 번에 하나의 로커 만 허용하고 소유권 제한이 세마포어보다 더 엄격 할 수 있는 상호 배제 개체 입니다.

이것은 (a) 를 잠근 동일한 스레드에 의해서만 해제 될 수 있어야한다는 요구 사항과 일반 계수 세마포 (1 개 포함)와 동등하다고 생각할 수 있습니다 .

반면 세마포어는 임의의 개수를 가지며 동시에 많은 로커에 의해 잠길 수 있습니다. 그리고 그것을 주장한 동일한 스레드에 의해 릴리스되어야한다는 요구 사항이 없을 수도 있습니다 (그러나 그렇지 않은 경우 할당 된 메모리와 같이 현재 책임이있는 사람을 신중하게 추적해야합니다).

따라서 리소스 인스턴스 (예 : 테이프 드라이브 3 개)가 여러 개있는 경우 개수가 3 인 세마포어를 사용할 수 있습니다.이 값은 보유하고있는 테이프 드라이브를 알려주는 것이 아니라 특정 숫자.

또한 세마포어를 사용하면 단일 로커가 테이프 간 복사와 같이 리소스의 여러 인스턴스를 잠글 수 있습니다. 하나의 리소스 (손상하지 않으려는 메모리 위치)가있는 경우 뮤텍스가 더 적합합니다.

동등한 작업은 다음과 같습니다.

Counting semaphore          Mutual exclusion semaphore
--------------------------  --------------------------
  Claim/decrease (P)                  Lock
  Release/increase (V)                Unlock

곁에 : 세마포어를 주장하고 해제하는 데 사용되는 기괴한 편지에 대해 궁금해 한 적이 있다면 발명가가 네덜란드 사람이기 때문입니다. Probeer te verlagen은 시도하고 감소하는 것을 의미하고 verhogen은 증가하는 것을 의미합니다.


(a) ... 또는 세마포어와는 완전히 다른 것으로 생각할 수 있으며, 거의 항상 다른 용도로 사용하면 더 안전 할 수 있습니다.


좋아, 나도 이진 세마포어를 발견했다. 바이너리 세마포어를 위해 언제 들어가야하고 언제 뮤텍스를 사용해야합니까?
Karthik Balaguru

개념적으로 이진 세마포어 뮤텍스이며 한 카운트가있는 일반 세마포어와 동일합니다. 효율성 또는 리소스 소유권과 같은 개념 구현 에 차이가있을 수 있습니다 (청구자 이외의 사람이 해제 할 수 있지만 BTW에 동의하지 않습니다. 리소스는 리소스를 주장한 스레드에서만 해제 할 수 있어야합니다. ).
paxdiablo

1
또 다른 잠재적 구현 차이점은 재귀 뮤텍스입니다. 리소스가 하나뿐이기 때문에 단일 스레드가 여러 번 잠글 수 있습니다 (여러 번 해제하는 한). 스레드가 다른 인스턴스 또는 동일한 인스턴스를 다시 요구할지 여부를 알 수 없기 때문에 다중 인스턴스 리소스의 경우 그렇게 쉽지 않습니다 .
paxdiablo

1
그들은 특정 문제를 해결합니다. 그들이 해결할 문제가없는 사람이라는 사실 매우 :-) 솔루션 과소 평가 어떠한 방식으로, 뮤텍스를해야 grok 수
paxdiablo

5
뮤텍스는 이진 세마포어와 완전히 다릅니다. 죄송하지만이 정의는 잘못되었습니다
Peer Stritzinger

49

뮤텍스 카운트 1을 가진 세마포 가 아니라는 것을 이해하는 것이 매우 중요합니다 !

이것이 바이너리 세마포어 (실제로 카운트 1의 세마포어)와 같은 것이있는 이유입니다.

Mutex와 Binary-Semaphore의 차이점은 소유권 원칙입니다.

뮤텍스는 작업에 의해 획득되므로 동일한 작업에 의해 해제되어야합니다. 이를 통해 이진 세마포어 (우연 릴리스, 재귀 교착 상태 및 우선 순위 반전)의 여러 문제를 해결할 수 있습니다.

주의 사항 : 이러한 문제를 해결하는 방법과 방법은 OS 구현에 달려 있습니다.

뮤텍스는 동일한 작업에 의해 해제되어야하므로 작업 동기화에 적합하지 않습니다. 그러나 조건 변수와 결합하면 모든 종류의 ipc 프리미티브를 구축하기위한 매우 강력한 빌딩 블록을 얻을 수 있습니다.

그래서 내 권장 사항은 : 뮤텍스와 조건 변수 (POSIX pthreads와 같은)를 깨끗하게 구현했다면 이것을 사용하십시오.

해결하려는 문제에 정확히 맞는 경우에만 세마포어를 사용하고, 다른 기본 요소를 빌드하지 마십시오 (예 : 세마포어에서 rw-locks, 뮤텍스 및 조건 변수 사용).

많은 오해가있는 뮤텍스와 세마포어가 있습니다. 지금까지 찾은 가장 좋은 설명은이 3 부 문서입니다.

뮤텍스 대 세마포 – 파트 1 : 세마포

뮤텍스 대 세마포어 – 파트 2 : 뮤텍스

뮤텍스 대 세마포어 – 파트 3 (마지막 파트) : 상호 배제 문제


이 사이트의 URL에는 펑키 한 문자가 포함되어 있으므로 작동하지 않습니다 ... 작업 중입니다
Peer Stritzinger

13

@opaxdiablo 대답은 완전히 정확하지만 두 가지 사용 시나리오가 상당히 다르다는 점을 지적하고 싶습니다. 뮤텍스는 코드의 일부가 동시에 실행되지 않도록 보호하는 데 사용되며, 세마포어는 한 스레드가 다른 스레드가 실행되도록 신호를 보내는 데 사용됩니다.

/* Task 1 */
pthread_mutex_lock(mutex_thing);
    // Safely use shared resource
pthread_mutex_unlock(mutex_thing);



/* Task 2 */
pthread_mutex_lock(mutex_thing);
   // Safely use shared resource
pthread_mutex_unlock(mutex_thing); // unlock mutex

세마포어 시나리오는 다릅니다.

/* Task 1 - Producer */
sema_post(&sem);   // Send the signal

/* Task 2 - Consumer */
sema_wait(&sem);   // Wait for signal

자세한 설명 은 http://www.netrino.com/node/202 를 참조하십시오 .


2
네가 옳아. 카운트가 1 인 세마포어를 사용하더라도 뮤텍스를 사용하는 것보다 수행중인 작업에 대해 암시하는 것입니다.
Omnifarious

나는 그것에 동의하는지 확신하지 못하지만, 내가 당신을 비판 할 정도로 격렬하게 동의 하지는 않습니다. :-) 당신은 세마포어의 사용 패턴이 스레드를 알리는 것이라고 말하지만 다른 스레드가 기다리고있을 때 뮤텍스가하는 일입니다. 거기에, 세마포어가 정확히 무엇을 하지 않습니다 에 어떤 스레드가 없을 때 sema_wait:-) 제 생각에는, 그들이있어 모두 자원에 대한 다른 스레드을 물려 알림이 (매우 중요, 성능 현명한)의 부작용입니다 보호.
paxdiablo

You say that the usage pattern of semaphores is to notify threads스레드 알림에 대한 1 점. 당신은 호출 할 수 있습니다 sem_post안전하게 신호 처리기 (에서 pubs.opengroup.org/onlinepubs/009695399/functions/... ) 있지만 호출에 사용하지 않는 것이 좋습니다 pthread_mutex_lockpthread_mutex_unlock(신호 처리기에서 manpages.ubuntu.com/manpages/lucid/man3/... )

@paxdiablo :이 뮤텍스 바이너리 세마포어 사이에는 참조 횟수를 유지하는 것이 한 가지 큰 차이점이 있습니다. 뮤텍스 또는 조건부 뮤텍스가 카운트를 유지하기 위해 sempahore가 사용하는 잠금과 관련된 카운트를 유지하지 않는다고 말할 수 있습니다. 따라서 sem_wait 및 sem_post는 개수를 유지합니다.
Prak 2013-07-14

9

"화장실 예제" -http : //pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm 참조 :

뮤텍스 :

화장실의 열쇠입니다. 한 사람이 열쇠를 가질 수 있습니다 (화장실 점유). 완료되면 그 사람은 대기열에있는 다음 사람에게 키를 제공 (해제)합니다.

공식적으로 : "뮤텍스는 일반적으로 하나 이상의 스레드에서 동시에 실행할 수없는 재진입 코드 섹션에 대한 액세스를 직렬화하는 데 사용됩니다. 뮤텍스 객체는 제어 된 섹션에 하나의 스레드 만 허용하므로 다른 스레드는 액세스를 시도합니다. 해당 섹션에서 첫 번째 스레드가 종료 될 때까지 대기합니다. " 참조 : Symbian 개발자 라이브러리

(뮤텍스는 실제로 값이 1 인 세마포어입니다.)

신호기:

무료 동일한 변기 키의 수입니다. 예를 들어, 자물쇠와 열쇠가 동일한 화장실이 4 개 있다고 가정 해 보겠습니다. 세마포어 개수 (키 개수)는 처음에 4로 설정되고 (4 개의 화장실 모두 사용 가능), 사람이 들어올 때 개수 값이 감소합니다. 모든 화장실이 가득 찬 경우, 즉. 남은 빈 키가 없으며 세마포어 카운트는 0입니다. 이제 eq. 한 사람이 화장실을 떠나면 세마포어가 1 (무료 키 하나)로 증가하고 대기열에있는 다음 사람에게 제공됩니다.

공식적으로 : "세마포어는 공유 리소스의 동시 사용자 수를 최대 수로 제한합니다. 스레드는 리소스에 대한 액세스를 요청할 수 있으며 (세마포어 감소), 리소스 사용이 완료되었음을 알릴 수 있습니다 (세마포어 증가). " 참조 : Symbian 개발자 라이브러리


7

엉뚱한 소리를 내지 않으려 고 노력하지만 나 자신을 도울 수 없습니다.

귀하의 질문은 뮤텍스와 세마포어의 차이점은 무엇입니까? 그리고 더 정확한 질문은 '뮤텍스와 세마포어 사이의 관계는 무엇입니까?'입니다.

(나는 그 질문을 추가했을 것이지만, 어떤 지나치게 열성적인 중재자가 차이점과 관계의 차이를 이해하지 않고 중복으로 닫을 것이라고 확신합니다.)

객체 용어에서 우리는 다음을 관찰 할 수 있습니다.

관찰 .1 세마포는 뮤텍스를 포함합니다.

관찰 .2 뮤텍스는 세마포어가 아니고 세마포어는 뮤텍스가 아닙니다.

이진 세마포어라고 불리는 뮤텍스 인 것처럼 작동하는 세마포어가 있지만 뮤텍스가 아닙니다.

뮤텍스에서 세마포어를 만드는 데 필요한 Signaling (posix는 해당 이름에 condition_variable을 사용함)이라는 특수 요소가 있습니다. 알림 소스로 생각하십시오. 두 개 이상의 스레드가 동일한 알림 소스에 가입되어 있으면 ONE 또는 ALL에 메시지를 보내 깨울 수 있습니다.

뮤텍스에 의해 보호되는 세마포어와 관련된 하나 이상의 카운터가있을 수 있습니다. 세마포어에 대한 가장 간단한 시나리오는 0 또는 1이 될 수있는 단일 카운터가 있습니다.

몬순 비처럼 혼란이 쏟아지는 곳입니다.

카운터가 0 또는 1 일 수있는 세마포어는 뮤텍스가 아닙니다.

Mutex에는 두 가지 상태 (0,1)와 하나의 소유권 (작업)이 있습니다. 세마포어에는 뮤텍스, 일부 카운터 및 조건 변수가 있습니다.

이제 상상력을 사용하면 카운터 사용과 신호시기의 모든 조합이 한 가지 종류의 세마포어를 만들 수 있습니다.

  1. 값이 0 또는 1 인 단일 카운터 및 값이 1이 될 때 신호를 보내고 신호를 기다리는 사람 중 하나를 잠금 해제합니다. == 이진 세마포어

  2. 값이 0 ~ N 인 단일 카운터 및 값이 N 미만이 될 때 신호를 보내고 값이 N 일 때 잠금 / 대기 == 세마포어 계산

  3. 값이 0 ~ N 인 단일 카운터와 값이 N이 될 때 신호를 보내고, 값이 N보다 작을 때 잠금 / 대기합니다. == Barrier semaphore

이제 귀하의 질문에 언제 무엇을 사용해야합니까? (또는 뮤텍스를 사용할 때와 이진 세마포어를 사용하는 경우가 아닌 올바른 질문 버전 .3. 이진 세마포어가 아닌 것과 비교가 없기 때문에 뮤텍스를 사용하십시오.) 1. 바이너리에서 제공하지 않는 사용자 정의 된 동작을 원할 때 뮤텍스를 사용하십시오. 세마포어 (예 : 스핀 잠금 또는 빠른 잠금 또는 재귀 잠금). 일반적으로 속성을 사용하여 뮤텍스를 사용자 정의 할 수 있지만 세마포를 사용자 정의하는 것은 새 세마포를 작성하는 것에 불과합니다. 2. 가볍거나 더 빠른 기본 요소를 원합니다.

원하는 것이 정확히 제공되면 세마포어를 사용하십시오.

바이너리 세마포어 구현에서 제공하는 내용을 이해하지 못하면 IMHO, 뮤텍스를 사용하십시오.

그리고 마지막으로 너무 의존하기보다는 책을 읽으십시오.


5

질문은 뮤텍스와 이진 세마포어의 차이 여야한다고 생각합니다.

Mutex = 소유권 잠금 메커니즘이며 잠금을 획득 한 스레드 만 잠금을 해제 할 수 있습니다.

이진 세마포어 = 신호 메커니즘에 가깝고 우선 순위가 높은 다른 스레드는 신호를 보내고 잠금을 취할 수 있습니다.


5

Mutex는 공유 자원을 보호하는 것입니다.
세마포어는 스레드를 디스패치하는 것입니다.

Mutex :
판매 할 티켓이 있다고 상상해보십시오. 많은 사람들이 티켓을 동시에 구매하는 경우를 시뮬레이션 할 수 있습니다. 각 사람은 티켓을 구매하는 스레드입니다. 분명히 공유 리소스이기 때문에 티켓을 보호하기 위해 뮤텍스를 사용해야합니다.


세마포 :
다음과 같이 계산을해야한다고 상상해보십시오.

c = a + b;

또한 geta()계산할 함수 a, 계산할 함수 및 getb()계산 을 수행 b하는 함수 getc()가 필요합니다 c = a + b.

분명히, 우리는 할 수 없어 c = a + b하지 않는 geta()getb()완료되었다.
3 개의 함수가 3 개의 스레드이면 3 개의 스레드를 디스패치해야합니다.

int a, b, c;
void geta()
{
    a = calculatea();
    semaphore_increase();
}

void getb()
{
    b = calculateb();
    semaphore_increase();
}

void getc()
{
    semaphore_decrease();
    semaphore_decrease();
    c = a + b;
}

t1 = thread_create(geta);
t2 = thread_create(getb);
t3 = thread_create(getc);
thread_join(t3);

세마포어의 도움으로, 위의 코드는 확인 할 수 t3그것의 일을 전까지하지 않을 것이다 t1그리고 t2자신의 작업을 수행했다.

한마디로, 세마포어는 스레드를 논리적 인 순서로 실행하는 반면 뮤텍스는 공유 리소스를 보호하는 것입니다.
따라서 뮤텍스가 초기 값이 1 인 특수 세마포어라고 항상 말하는 사람이 있어도 동일하지 않습니다. 이와 같이 말할 수도 있지만 다른 경우에 사용된다는 점에 유의하십시오. 할 수 있더라도 하나씩 교체하지 마십시오.


티켓 판매가 좋은 예입니다. 세마포어 예제는 약간 불분명합니다 (어쨌든 나에게).
prayagupd

1
@prayagupd Semaphore 예제는 어떤 순서로 스레드를 만드는 반면 티켓 판매에는 주문이 필요하지 않습니다. 세 사람이있는 경우 : a, b 및 c. 그들이 티켓을 사러 올 때, 우리는 티켓을 사는 순서를 전혀 신경 쓰지 않습니다. 우리는 이러한 계산을 할 경우, : x = getx(); y = gety(); z = x + y;우리가 할 수 없기 때문에 어떤 이유로, 우리는 세 가지를 할 세 가지 스레드를 사용, 현재 스레드의 순서는 매우 중요 x + y하지 않는 getxgety완료. 한마디로, 세마포어는 멀티 스레딩의 실행 순서에 관심을 가질 때 사용됩니다.
이브

잡았다. 장벽 과 비슷하게 들립니다 . 나는 스레드 때까지 그 대기를 말할 수 xy다음 계산을 완료 z = x + y. 나는 자바에 CyclicBarrier. 또한 모든 s가 완료 될 때까지 mapreduce할 수 없기 때문에 세마포어 사용 사례 라고 말할 수 있는지 확실 하지 않습니다 . reducemap
prayagupd

@prayagupd 예. 그렇게 말할 수 있습니다.
이브

2

위의 모든 답변은 좋은 품질의, 그러나 이것은 memorize.The 이름에 그냥 뮤텍스 에서 파생 상호 배타적 따라서 당신은 한 번에 하나 같은 둘 사이의 상호 배제와 같은 뮤텍스 잠금 생각하는 동기, 그리고 경우 내가 그것을 놓은 후에 만 ​​그것을 가질 수있다. 반면에 Semaphore 에게는 그러한 경우가 존재하지 않는다는 것은 교통 신호와 같다 (Semaphore라는 단어도 의미한다).


1

지적했듯이 카운트가 1 인 세마포어는 뮤텍스와 동일한 '바이너리'세마포어와 동일합니다.

내가 사용한 세마포어 수가 1보다 큰 세마포어를 본 주요 것은 특정 고정 크기의 대기열이있는 생산자 / 소비자 상황입니다.

그러면 두 개의 세마포가 있습니다. 첫 번째 세마포어는 초기에 대기열의 항목 수로 설정되고 두 번째 세마포어는 0으로 설정됩니다. 생산자는 첫 번째 세마포어에서 P 작업을 수행하고 대기열에 추가합니다. 두 번째에 V 연산을 수행합니다. 소비자는 두 번째 세마포어에서 P 작업을 수행하고 대기열에서 제거한 다음 첫 번째 세마포어에서 V 작업을 수행합니다.

이러한 방식으로 생산자는 대기열을 채울 때마다 차단되고 소비자는 대기열이 비어있을 때마다 차단됩니다.


1

뮤텍스는 세마포어의 특별한 경우입니다. 세마포어를 사용하면 여러 스레드가 중요 섹션으로 이동할 수 있습니다. 세마포어를 만들 때 임계 섹션에서 스레드를 허용하는 방법을 정의합니다. 물론 코드는이 중요한 섹션에 대한 여러 액세스를 처리 할 수 ​​있어야합니다.


-1

이진 세마포어와 뮤텍스는 다릅니다. OS 관점에서 이진 세마포어와 카운팅 세마포어는 동일한 방식으로 구현되며 이진 세마포어는 값 0 또는 1을 가질 수 있습니다.

Mutex- > 중요한 코드 섹션에 대해 상호 배제의 유일한 목적으로 만 사용할 수 있습니다.

세마포어 -> 다양한 문제를 해결하는 데 사용할 수 있습니다. 이진 세마포어는 신호 전달에 사용될 수 있으며 상호 배제 문제도 해결할 수 있습니다. 초기화되면 0 , 그것을 해결 시그널링 문제 및 초기화 할 때 1 , 그것을 해결하는 상호 배제 문제.

리소스 수가 더 많고 동기화가 필요한 경우 카운팅 세마포어를 사용할 수 있습니다.

내 블로그에서 이러한 주제에 대해 자세히 논의했습니다.

https://designpatterns-oo-cplusplus.blogspot.com/2015/07/synchronization-primitives-mutex-and.html

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