[C++] counting_semaphore/binary_semaphore
Updated:
개요
- 공유 리소스에 대한 접근을 제어하는 경량화 된 동기화 클래스
- 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()
- 내부 카운터가 가질 수 있는 최대 값을 반환
- release()
예제
- 코드
#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