Updated:

1 minute read

개요

  • 공유 리소스에 대한 접근을 제어하는 경량화 된 동기화 클래스
  • binary_semaphore는 크기가 1인 counting_semaphore
  • 상호 배제보다 신호/알림에 자주 사용
    • condition_variable의 대안이면 종종 더 나은 성능 제공
  • condition_variable::wait()과 유사하게 spurious wakeup 주의 필요
  • mutex와의 차이점
    • 크기만큼 동시 접근 가능
    • 실행 스레드에 연결되지 않음
      • 실행 스레드와 상관 없이 동시 수행 가능
  • 멤버 함수
    • release()
      • 내부 카운터 증가 및 acquire() 차단 해제
    • acquire()
      • 내부 카운터 감소
      • 내부 카운터가 0이면 내부 카운터가 증가할 때까지 차단
    • try_acquire()
      • 내부 카운터 감소
      • 차단 하지 않음
    • try_acquire_for()
      • 내부 카운터 감소
      • 내부 카운터가 0이면 내부 카운터가 증가하거나 특정 시간동안 차단
    • try_acquire_until()
      • 내부 카운터 감소
      • 내부 카운터가 0이면 내부 카운터가 증가하거나 특정 시점까지 차단
    • max()
      • 내부 카운터가 가질 수 있는 최대 값을 반환


예제

  • 코드
     #include <algorithm>
     #include <chrono>
     #include <future>
     #include <iostream>
     #include <semaphore>
     #include <thread>
        
     using namespace std;
        
     counting_semaphore semaphore{1};
        
     int main() {
         cout << semaphore.max() << endl;
        
         auto f1 = async(launch::async, []() {
             for (int i = 0; i < 3; ++i) {
                 cout << "send" << endl;
                 semaphore.release();
        
                 this_thread::sleep_for(chrono::seconds(1));
             }
         });
        
         auto f2 = async(launch::async, []() {
             int count = 0;
        
             while (count < 3) {
                 semaphore.acquire();
                 cout << "recv" << endl;
                 ++count;
             }
         });
        
         f1.get();
         f2.get();
        
         return 0;
     }
    
  • 실행 결과
     2147483647
     send
     recv
     recv
     send
     recv
     send