1 분 소요

개요

  • 공유 리소스에 대한 접근을 제어하는 경량화 된 동기화 클래스
  • 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