세마포 란 무엇입니까?


349

세마포어는 다중 스레딩 문제를 해결하는 데 자주 사용되는 프로그래밍 개념입니다. 커뮤니티에 대한 나의 질문 :

세마포 란 무엇이며 어떻게 사용합니까?


14
정수 카운터가 지정된 상한에 도달했는지 여부에 따라 값이 결정되는 부울 플래그 최대 난독 화!
Sam

답변:


399

나이트 클럽에서 세마포어를 경비원으로 생각하십시오. 클럽에는 한 번에 허용 된 인원이 있습니다. 클럽이 가득 차면 아무도 입장 할 수 없지만 한 사람이 떠나면 다른 사람이 입장 할 수 있습니다.

특정 리소스에 대한 소비자 수를 제한하는 방법 일뿐입니다. 예를 들어, 응용 프로그램의 데이터베이스에 대한 동시 호출 수를 제한합니다.

다음은 C #에서 매우 교육적인 예입니다.

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);
        }
    }
}

6
나이트 클럽의 경비원과 같은 경우 손님이 순차적으로 입장하도록해야하지만 내가 시험해 보았을 때 무작위입니다. 예 : 40 번 손님은 39 번 손님보다 먼저 오셨습니다. 이것을 통제하기 위해 할 수있는 일이 있습니까?
TNA

2
@TNA : 그렇습니다.이 예제에서 새로운 스레드가 시작되는 방식과 관련이 있으며 실제로는 대답의 범위가 아닙니다.
Patrik Svensson

5
경비원의 비유는 실제로 서사적이지만 흥미롭게도 이미 사용되었습니다 : albahari.com/threading/part2.aspx#_Semaphore
Igor Brejc

분산 시스템에서 세마포어는 어떤 가치를 제공합니까?
csandreas1

198

마이클 바 (Michael Barr)가 해석뮤텍스와 세마포어 (Mutexes and Semaphores) 라는 기사 는 뮤텍스와 세마포어 를 어떻게 다르게 만드는지, 언제 사용해야하는지와 사용하지 않아야 할 때에 대한 짧은 소개입니다. 여기서 몇 가지 주요 단락을 발췌했습니다.

핵심은 공유 리소스를 보호하기 위해 뮤텍스를 사용해야하고 시그널링에는 세마포어를 사용해야한다는 것입니다. 일반적으로 공유 리소스를 보호하기 위해 세마포어를 사용하거나 시그널링을위한 뮤텍스를 사용해서는 안됩니다. 예를 들어 공유 자원을 보호하기 위해 세마포어를 사용한다는 점에서 경비원 비유와 관련된 문제가 있습니다. 이러한 방식으로 사용할 수는 있지만 버그를 진단하기가 어려울 수 있습니다.

뮤텍스와 세마포어는 구현 방식이 유사하지만 항상 다르게 사용해야합니다.

맨 위에 제기 된 질문에 대한 가장 일반적인 (그러나 그럼에도 불구하고 잘못된) 대답은 뮤텍스와 세마포어가 매우 유사하다는 것입니다. 단, 세마포어가 1보다 많을 수 있다는 점만 다릅니다. 거의 모든 엔지니어는 뮤텍스가 중요한 코드 섹션 내에서 상호 배제를 보장함으로써 공유 리소스를 보호하는 데 사용되는 이진 플래그임을 제대로 이해하는 것 같습니다. 그러나 "카운팅 세마포어"를 사용하는 방법을 확장하라는 요청을 받았을 때 대부분의 엔지니어는 자신의 신뢰도만으로도 여러 등가 자원을 보호하는 데 사용된다는 교과서 의견의 일부를 표현합니다.

...

이 시점에서 화장실 키를 공유 리소스를 보호하는 욕실이라는 아이디어를 사용하여 흥미로운 비유를합니다. 상점에 단일 욕실이있는 경우 단일 자원만으로도 해당 자원을 보호하고 여러 사람이 동시에 사용할 수 없게됩니다.

욕실이 여러 개인 경우 욕실을 똑같이 키우고 여러 개의 키를 만들고 싶은 유혹이있을 수 있습니다. 일단 열쇠가 있으면 실제로 어떤 화장실이 있는지 알 수 없으며이 경로를 따라 가면 뮤텍스를 사용하여 정보를 제공하고 이미 차지한 화장실을 가져 가지 않을 것입니다. .

세마포어는 본질적으로 동일한 리소스를 보호하기위한 잘못된 도구이지만 많은 사람들이이를 생각하고 사용합니다. 경비원의 비유는 분명히 다릅니다. 동일한 유형의 리소스가 여러 개가 아니라 여러 명의 동시 사용자를 허용 할 수있는 리소스가 하나 있습니다. 나는 그러한 상황에서 세마포어를 사용할 수 있다고 생각하지만 실제로는 비유가 실제로 실제 상황에서 거의 존재하지 않습니다. 더 자주 같은 유형의 여러 가지가 있지만 여전히 화장실과 같은 개별 리소스가있을 수는 없습니다. 이 방법.

...

세마포어를 올바르게 사용하려면 한 작업에서 다른 작업으로 신호를 보냅니다. 뮤텍스는 보호되는 공유 리소스를 사용하는 각 작업에 의해 항상 순서대로 가져와 해제됩니다. 대조적으로, 세마포어를 사용하는 작업은 신호 또는 대기 중 하나가 아닌 신호입니다. 예를 들어, 작업 1은 "전원"버튼을 눌렀을 때 특정 세마포를 게시 (즉, 신호 또는 증분)하는 코드를 포함 할 수 있고 디스플레이를 깨우는 작업 2는 동일한 세마포어에 종속됩니다. 이 시나리오에서 하나의 작업은 이벤트 신호의 생성자입니다. 다른 소비자.

...

여기서 뮤텍스가 실시간 운영 체제를 나쁜 방식으로 방해하여 리소스 공유로 인해 더 중요한 작업보다 덜 중요한 작업이 실행될 수있는 우선 순위 반전이 발생한다는 중요한 점이 있습니다. 즉, 우선 순위가 낮은 작업이 뮤텍스를 사용하여 리소스 A를 잡고 B를 잡으려고 시도하지만 B를 사용할 수 없기 때문에 일시 중지됩니다. 기다리는 동안 우선 순위가 높은 작업이 필요하고 A가 필요하지만 이미 묶여 ​​있으며 B를 기다리고 있기 때문에 실행되지 않는 프로세스에 의해 해결됩니다. 해결 방법에는 여러 가지가 있지만 가장 자주 해결됩니다. 뮤텍스 및 작업 관리자를 변경하여 이 경우 뮤텍스는 이진 세마포어보다 훨씬 더 복잡합니다.

...

뮤텍스와 세마포어 사이의 광범위한 현대 혼란의 원인은 Djikstra의 1974 년 세마포어 (자본 "S")의 발명으로 거슬러 올라가는 역사가 있습니다. 그 이전에는 컴퓨터 과학자들에게 알려진 인터럽트 안전 작업 동기화 및 신호 메커니즘 중 어느 것도 3 개 이상의 작업에 효율적으로 확장 할 수 없었습니다. Dijkstra의 혁신적이고 안전하고 확장 가능한 세마포어는 중요한 섹션 보호 및 신호 처리에 모두 적용되었습니다. 그래서 혼란이 시작되었습니다.

그러나 우선 순위 기반 선점 형 RTOS (예 : VRTX, ca. 1980)가 등장한 후 RMA를 설정하는 학술 논문 및 우선 순위 반전으로 인한 문제 및 우선 순위에 관한 논문이 발표 된 후 운영 체제 개발자에게 분명해졌습니다. 1990 년의 상속 프로토콜, 3 뮤텍스는 이진 카운터를 갖는 단순한 세마포 이상이어야한다는 것이 명백 해졌다.

뮤텍스 : 리소스 공유

세마포어 : 신호

부작용을 신중하게 고려하지 않고 다른 것을 사용하지 마십시오.


10
이 스탠포드 동시성 PDF 문서를보십시오. 8 페이지를보십시오. 위의 설명은 더 의미가 있습니다 .. see.stanford.edu/materials/icsppcs107/…
Kris Subramanian

3
세마포어작은 책 은 이러한 문제에 대한 귀중한 정보입니다.
G. 바흐

@KrisSubramanian 링크 감사합니다. 그러나이 문서는 세마포어에 대해서는 논의하고 Mutexes에서는 아무것도 다루지 않습니다. 그러나 예제의 공유 버퍼를 Mutex를 사용하여 보호 할 수 있습니까? 2 개의 세마포어 대신 emptyBuffers와 fullBuffers
talekeDskobeDa

1
@ 프라 모 True. 이 링크는 Mutex 관련 메모를 추가하지 않습니다. 세마포어 측면이 SO 독자에게 명확 해 지도록 링크를 추가했습니다. :) 흥미롭게도이 경우 버퍼는 순차적으로 그리고 순환 형식으로 액세스되므로 잠금없이 사용됩니다. 즉, Writer는 0에 쓰고 리더에게 0에서 읽도록 지시합니다. 리더가 0에서 읽지 않고 라이터에 신호를 보내면 라이터는 차단됩니다. 따라서 공통 자원을 잠그기 위해 뮤텍스를 사용할 필요가 없습니다. 이것은 위에서 주어진 욕실 비유와 다릅니다.
Kris Subramanian

@Kris Subramanian : 훌륭한 문서이지만 작은 오도 포함 : 세 번째 페이지는 "세마포어를 잠그는 각 스레드는 잠금을 해제하는 데주의해야합니다"라고 표시합니다. 모든 스레드에서 잠금을 해제 할 수 있습니다. 같은 스레드에서 수행하면 "브록 큰 뮤텍스"로 사용됩니다. "실수"-실수로 다른 스레드에서 실수로 잠금을 해제 할 수 있기 때문에 실수가 발생하여 논리가 깨집니다. 아직도 좋은 의사, 생각.
Rustam A.

70

Mutex : 리소스에 대한 독점 멤버 액세스

세마포어 : 리소스에 대한 n- 멤버 액세스

즉, 뮤텍스를 사용하여 카운터, 파일, 데이터베이스 등에 대한 액세스를 동기화 할 수 있습니다.

Sempahore는 동일한 작업을 수행 할 수 있지만 고정 된 수의 동시 발신자를 지원합니다. 예를 들어, 데이터베이스 스레드를 세마포어 (3)로 감싸서 멀티 스레드 앱이 최대 3 개의 동시 연결로 데이터베이스에 도달하도록 할 수 있습니다. 세 슬롯 중 하나가 열릴 때까지 모든 시도가 차단됩니다. 순진한 스로틀 링과 같은 작업을 정말 쉽고 쉽습니다.


20
Richard W. Stevens에 따르면, 뮤텍스는 실제로 이진 세마포어이며 가능한 값은 0과 1입니다.
Qiang Xu

19
William Stallings의 운영 체제 내부 및 설계 원칙의 @QiangXu 는 바이너리 세마포어가 하나의 중요한 점에서 뮤텍스와 다르다는 점을 인용합니다. "뮤텍스와 이진 세마포어의 주요 차이점은 뮤텍스를 잠그는 프로세스입니다. 반면에 한 프로세스는 이진 세마포어를 잠그고 다른 프로세스는 잠금을 해제 할 수 있습니다. " .
Electric Coffee

3
오래된 스레드에 주석을 달릴 위험이 있지만 이는 올바르지 않습니다. @AdamDavis가 위에서 언급했듯이 Semaphore는 n 멤버가 리소스에 액세스하는 데 사용되어서는 안됩니다. Mutex를 사용하여 여전히 수행해야합니다. 커피 숍의 화장실 비유를 고려해보십시오. 여러 사람이 화장실을 기다리는 중이거나 화장실과 비슷한 열쇠를 가진 여러 욕실이 있습니다. 오히려 세마포어를 사용하여 작업 간 신호를 보내야합니다.
cspider

21

3 (총 수용 할 수있는 택시 고려 후방 ) +2 ( 앞쪽 드라이버 포함) 명. 따라서 semaphore한 번에 5 명만 차 안에 실을 수 있습니다. 그리고 mutex자동차의 한 좌석에 한 사람 만 허용합니다.

따라서 Mutex( OS 스레드와 같은) 리소스에 대한 독점 액세스를 허용 하는 동시에 a Semaphore는 한 번 에 n 개의 리소스에 대한 액세스를 허용 하는 것입니다.


19

@ 크레이그 :

세마포어는 리소스를 잠그는 방법으로, 코드가 실행되는 동안이 코드 만 해당 리소스에 액세스 할 수 있습니다. 이렇게하면 두 스레드가 동시에 리소스에 액세스하지 못하게되므로 문제가 발생할 수 있습니다.

이것은 하나의 스레드에만 국한되지 않습니다. 고정 된 수의 스레드가 리소스에 액세스 할 수 있도록 세마포를 구성 할 수 있습니다.


7
이것은 해설이 아니라 대답입니다.
kaspersky

11
예, 그러나 의견이 Stack Overflow에 추가되기 전에 이것을 작성했다고 생각합니다. 또는 나는 기억하지 않았다. 이번에는 의견에 대답했습니다. :-)
Mats Fredriksson

16

세마포는 ... 세마포어로도 사용할 수 있습니다. 예를 들어 큐에 데이터를 큐에 넣는 프로세스가 여러 개이고 큐에서 데이터를 소비하는 작업이 하나만있는 경우 소비하는 작업이 사용 가능한 데이터에 대해 큐를 지속적으로 폴링하지 않게하려면 세마포어를 사용할 수 있습니다.

여기서 세마포어는 배제 메커니즘이 아니라 시그널링 메커니즘으로 사용된다. 소비 작업이 세마포어를 기다리고 있습니다 생산 작업이 세마포어에 게시되고 있습니다.

이렇게하면 대기열에서 빼낼 데이터가있을 때만 소비 작업이 실행됩니다


11

동시 프로그램을 구축하기 위해서는 동기화와 상호 배제라는 두 가지 필수 개념이 있습니다. 이 두 가지 유형의 잠금 (세마포가 일반적으로 일종의 잠금 메커니즘)이 동기화 및 상호 배제를 달성하는 데 어떻게 도움이되는지 살펴 보겠습니다.

세마포어는 동기화와 상호 배제를 구현하여 동시성을 달성하는 데 도움이되는 프로그래밍 구조입니다. 세마포어는 이진과 계산의 두 가지 유형입니다.

세마포어에는 카운터와 특정 리소스에 액세스하기 위해 대기중인 작업 목록의 두 부분이 있습니다. 세마포어는 두 가지 작업을 수행합니다. 대기 (P) [잠금 획득과 유사] 및 릴리스 (V) [잠금 해제와 유사] – 세마포어에서 수행 할 수있는 유일한 두 작업입니다. 이진 세마포어에서 카운터는 논리적으로 0과 1 사이입니다. 두 개의 값 (열림 / 닫힘)을 가진 잠금과 비슷하다고 생각할 수 있습니다. 카운팅 세마포어에는 count 값이 여러 개 있습니다.

이해해야 할 것은 세마포 카운터가 차단할 필요가없는 작업의 수를 추적한다는 것입니다. 즉, 진행할 수 있습니다. 작업이 카운터되고 카운터가 0 일 때만 세마포어 목록에 추가됩니다. 따라서 작업을 진행할 수 없으면 P () 루틴의 목록에 작업이 추가되고 V () 루틴을 사용하여 "해제"됩니다.

이제 바이너리 세마포어를 사용하여 동기화 및 상호 배제를 해결하는 방법을 알 수 있습니다. 본질적으로 잠금입니다.

전의. 동기화:

thread A{
semaphore &s; //locks/semaphores are passed by reference! think about why this is so.
A(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
;// some block of code B2
...
}

//thread B{
semaphore &s;
B(semaphore &s): s(s){} //constructor
foo(){
...
...
// some block of code B1
s.V();
..
}

main(){
semaphore s(0); // we start the semaphore at 0 (closed)
A a(s);
B b(s);
}

위의 예에서 B2는 B1이 실행을 완료 한 후에 만 ​​실행할 수 있습니다. 스레드 A가 먼저 실행되고 카운터가 0 (닫힘)이므로 sem.P ()에 도달하고 대기한다고 가정합니다. 스레드 B가 함께 나오고 B1을 완료 한 다음 스레드 A를 해제하여 B2를 완료합니다. 그래서 우리는 동기화를 달성합니다.

이제 이진 세마포어와의 상호 배제를 살펴 보자.

thread mutual_ex{
semaphore &s;
mutual_ex(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
//critical section
s.V();
...
...
s.P();
//critical section
s.V();
...

}

main(){
semaphore s(1);
mutual_ex m1(s);
mutual_ex m2(s);
}

상호 배제도 매우 간단합니다. m1과 m2는 동시에 임계 구역에 들어갈 수 없습니다. 따라서 각 스레드는 동일한 세마포어를 사용하여 두 개의 중요한 섹션에 대한 상호 배제를 제공합니다. 이제 더 큰 동시성을 가질 수 있습니까? 중요한 섹션에 따라 다릅니다. (다른 방법으로 상호 배제를 달성하기 위해 세마포어를 어떻게 사용할 수 있는지 생각해보십시오. 힌트 힌트 : 필자는 반드시 하나의 세마포어 만 사용해야합니까?)

세마포 계산 : 둘 이상의 값을 가진 세마포. 이것이 무엇을 의미하는지 봅시다-하나 이상의 값을 가진 자물쇠 ?? 그래서 열리고 닫히고 ... 음. 상호 배제 또는 동기화에서 다단계 잠금은 어떤 용도로 사용됩니까?

두 가지 중 더 쉬운 방법을 보자.

카운팅 세마포어를 사용한 동기화 : 3 번 이후에 실행하려는 # 1과 2의 3 가지 작업이 있다고 가정 해 봅시다. 어떻게 동기화를 설계 하시겠습니까?

thread t1{
...
s.P();
//block of code B1

thread t2{
...
s.P();
//block of code B2

thread t3{
...
//block of code B3
s.V();
s.V();
}

따라서 세마포어가 닫힌 상태로 시작되면 t1 및 t2 블록이 세마포어 목록에 추가되는지 확인하십시오. 그런 다음 중요한 모든 t3가 나오고 사업을 마치고 t1과 t2를 해제합니다. 그들은 어떤 순서로 해방 되었습니까? 세마포어 목록의 구현에 따라 다릅니다. 선입 선출 (FIFO), 특정 우선 순위 등을 기반으로 할 수 있음 (참고 : t1과 t2가 특정 순서로 실행되기를 원하고 세마포어의 구현을 모르는 경우 P와 V를 정렬하는 방법에 대해 생각하십시오)

(발견 : V의 수가 P의 수보다 크면 어떻게됩니까?)

상호 배제 카운팅 세마포어를 사용하여 : 나는 당신이 이것을 위해 자신의 의사 코드를 구성하고 싶습니다 (일을 더 잘 이해하게 만듭니다!) . 이것이 의미하는 것은 N 개의 작업 (또는 원하는 경우 스레드)이 중요 섹션에 들어가 있지만 N + 1 번째 작업은 차단되고 (가장 좋아하는 차단 된 작업 목록에 표시됨) 누군가 V가 세마포어 일 때만 통과됩니다. 적어도 한 번. 따라서 세마포 카운터는 0과 1 사이에서 스윙하는 대신 이제 0과 N 사이로 이동하여 N 작업이 자유롭게 들어가고 나갈 수있게하여 아무도 막지 않습니다!

이제 어리석은 일이 왜 필요합니까? 둘 이상의 사람이 리소스에 액세스하지 못하게하는 상호 배제의 요점이 아닙니까? (힌트 힌트 ... 컴퓨터에 항상 하나의 드라이브 만있는 것은 아닙니다.

생각해보기 : 세마포 만 세면 상호 배제가 달성됩니까? 리소스의 인스턴스가 10 개이고 카운팅 세마포어를 통해 10 개의 스레드가 들어 와서 첫 번째 인스턴스를 사용하려고하면 어떻게됩니까?


7

세마포어는 두 개의 수정 작업이 정의 된 자연수 (즉, 0 이상의 정수)를 포함하는 객체입니다. 한 번의 조작으로 V자연에 1을 더합니다. 다른 연산 P은 자연수를 1만큼 감소시킵니다. 두 활동 모두 원자 적입니다 (즉, 다른 연산은 a V또는 a 와 동시에 실행할 수 없음 P).

자연수 0을 줄일 수 없으므로 P0을 포함하는 세마포어를 호출하면 숫자가 더 이상 0이 아니고 P성공적으로 (그리고 원자 적으로) 실행될 수있을 때까지 호출 프로세스 (/ 스레드)의 실행이 차단됩니다 .

다른 답변에서 언급했듯이 세마포어를 사용하면 특정 리소스에 대한 액세스를 최대 (그러나 가변적) 프로세스 수로 제한 할 수 있습니다.


7

아이디어를 이해하는 데 도움이되는 시각화를 만들었습니다. 세마포어는 멀티 스레딩 환경에서 공통 리소스에 대한 액세스를 제어합니다. 여기에 이미지 설명을 입력하십시오

ExecutorService executor = Executors.newFixedThreadPool(7);

Semaphore semaphore = new Semaphore(4);

Runnable longRunningTask = () -> {
    boolean permit = false;
    try {
        permit = semaphore.tryAcquire(1, TimeUnit.SECONDS);
        if (permit) {
            System.out.println("Semaphore acquired");
            Thread.sleep(5);
        } else {
            System.out.println("Could not acquire semaphore");
        }
    } catch (InterruptedException e) {
        throw new IllegalStateException(e);
    } finally {
        if (permit) {
            semaphore.release();
        }
    }
};

// execute tasks
for (int j = 0; j < 10; j++) {
    executor.submit(longRunningTask);
}
executor.shutdown();

산출

Semaphore acquired
Semaphore acquired
Semaphore acquired
Semaphore acquired
Could not acquire semaphore
Could not acquire semaphore
Could not acquire semaphore

기사의 샘플 코드


3

하드웨어 또는 소프트웨어 플래그. 멀티 태스킹 시스템에서 세마포어는 공통 자원의 상태를 나타내는 값을 갖는 변수로서, 자원을 필요로하는 프로세스는 세마포어를 점검하여 자원 상태를 판별 한 후 진행 방법을 결정합니다.


2

세마포어는 스레드 제한 기처럼 작동합니다.

예 : 100 개의 스레드 풀이 있고 일부 DB 작업을 수행하려는 경우 주어진 시간에 100 개의 스레드가 DB에 액세스하는 경우 DB에 잠금 문제가있을 수 있으므로 한 번에 제한된 스레드 만 허용하는 세마포어를 사용할 수 있습니다. 아래 예제에서는 한 번에 하나의 스레드 만 허용합니다. 스레드가 acquire()메소드를 호출하면 액세스 권한을 얻고 release()메소드를 호출 한 후 다음 스레드가 액세스 권한을 갖도록 액세스를 해제합니다.

    package practice;
    import java.util.concurrent.Semaphore;

    public class SemaphoreExample {
        public static void main(String[] args) {
            Semaphore s = new Semaphore(1);
            semaphoreTask s1 = new semaphoreTask(s);
            semaphoreTask s2 = new semaphoreTask(s);
            semaphoreTask s3 = new semaphoreTask(s);
            semaphoreTask s4 = new semaphoreTask(s);
            semaphoreTask s5 = new semaphoreTask(s);
            s1.start();
            s2.start();
            s3.start();
            s4.start();
            s5.start();
        }
    }

    class semaphoreTask extends Thread {
        Semaphore s;
        public semaphoreTask(Semaphore s) {
            this.s = s;
        }
        @Override
        public void run() {
            try {
                s.acquire();
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName()+" Going to perform some operation");
                s.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } 
    }

1

모든 사람들이 화장실에 가려고하는데 화장실에 열쇠가 몇 개만 있다고 상상해보십시오. 이제 키가 충분하지 않으면 그 사람은 기다려야합니다. 따라서 세마포어는 다른 프로세스 (욕실 관리자)가 액세스를 요청할 수있는 욕실 (시스템 자원)에 사용 가능한 키 세트를 나타내는 것으로 생각하십시오.

이제 두 가지 프로세스가 동시에 화장실에 가려고한다고 상상해보십시오. 그것은 좋은 상황이 아니며 세마포어가 이것을 막기 위해 사용됩니다. 불행하게도, 세마포어는 자발적인 메커니즘이며 프로세스 (우리의 욕실 사용자)는이를 무시할 수 있습니다 (즉, 키가 있어도 누군가는 여전히 문을 열 수 있습니다).

이진 / 뮤텍스 및 카운팅 세마포어 사이에도 차이가 있습니다.

http://www.cs.columbia.edu/~jae/4118/lect/L05-ipc.html 에서 강의 노트를 확인 하십시오 .


0

이것은 오래된 질문이지만 세마포어의 가장 흥미로운 용도 중 하나는 읽기 / 쓰기 잠금이며 명시 적으로 언급되지 않았습니다.

R / W 잠금은 간단한 방식으로 작동합니다. 독자에게는 하나의 허가를, 작가에게는 모든 허가를 사용하십시오. 실제로, ar / w 잠금의 간단한 구현이지만 병목이 될 수있는 읽기 (실제로 두 번) 메타 데이터 수정이 필요하지만 여전히 뮤텍스 또는 잠금보다 훨씬 우수합니다.

또 다른 단점은 세마포어가 공정한 것이거나 여러 요청에서 쓰기가 허가를 얻지 않는 한 작가가 오히려 쉽게 시작할 수 있다는 것입니다.

추가 읽기 :


-3

세마포어는 리소스를 잠그는 방법으로, 코드가 실행되는 동안이 코드 만 해당 리소스에 액세스 할 수 있습니다. 이렇게하면 두 스레드가 동시에 리소스에 액세스하지 못하게되므로 문제가 발생할 수 있습니다.


13
세마포가 아닌 뮤텍스처럼 들린다
Sam
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.