std:: counting_semaphore, std:: binary_semaphore
|
헤더 파일에 정의됨
<semaphore>
|
||
|
template
<
std::
ptrdiff_t
LeastMaxValue
=
/* implementation-defined */
>
class counting_semaphore ; |
(1) | (C++20부터) |
|
using
binary_semaphore
=
std
::
counting_semaphore
<
1
>
;
|
(2) | (C++20부터) |
counting_semaphore
는 공유 자원에 대한 접근을 제어할 수 있는 경량화된 동기화 기본 요소입니다.
std::mutex
와 달리,
counting_semaphore
는 최소
LeastMaxValue
개의 동시 접근자에 대해 동일한 자원에 대한 다중 동시 접근을 허용합니다.
LeastMaxValue
가 음수일 경우 프로그램의 형식이 올바르지 않습니다.
binary_semaphore
는
LeastMaxValue
가
1
인
std::counting_semaphore
특수화의 별칭입니다. 구현체들은
binary_semaphore
를
std::counting_semaphore
의 기본 구현보다 더 효율적으로 구현할 수 있습니다.
counting_semaphore
는 생성자에 의해 초기화된 내부 카운터를 포함합니다. 이 카운터는
acquire()
및 관련 메서드 호출로 감소되고,
release()
호출로 증가됩니다. 카운터가 0일 때,
acquire()
는 카운터가 증가할 때까지 블록하지만
try_acquire()
는 블록하지 않습니다;
try_acquire_for()
와
try_acquire_until()
은 카운터가 증가하거나 타임아웃에 도달할 때까지 블록합니다.
std::condition_variable::wait()
와 유사하게,
counting_semaphore
의
try_acquire()
는 가짜 실패(spurious failure)가 발생할 수 있습니다.
std::counting_semaphore
의 특수화는
DefaultConstructible
,
CopyConstructible
,
MoveConstructible
,
CopyAssignable
, 또는
MoveAssignable
이 아닙니다.
목차 |
데이터 멤버
| 멤버 이름 | 정의 |
counter
(private)
|
std::ptrdiff_t
타입의 내부 카운터.
( 설명 전용 멤버 객체* ) |
멤버 함수
counting_semaphore
를 생성합니다
(public member function) |
|
counting_semaphore
를 소멸시킵니다
(public member function) |
|
|
operator=
[deleted]
|
counting_semaphore
는 할당할 수 없습니다
(public member function) |
연산 |
|
|
내부 카운터를 증가시키고 획득자를 차단 해제합니다
(public member function) |
|
|
내부 카운터를 감소시키거나 감소할 수 있을 때까지 차단합니다
(public member function) |
|
|
내부 카운터를 차단 없이 감소시키려 시도합니다
(public member function) |
|
|
내부 카운터를 감소시키려 시도하며, 최대 지정 시간 동안 차단합니다
(public member function) |
|
|
내부 카운터를 감소시키려 시도하며, 지정 시간까지 차단합니다
(public member function) |
|
상수 |
|
|
[static]
|
내부 카운터의 가능한 최댓값을 반환합니다
(public static member function) |
참고 사항
이름에서 알 수 있듯이,
LeastMaxValue
는
최소
최댓값이지
실제
최댓값이 아닙니다. 따라서
max()
는
LeastMaxValue
보다 큰 숫자를 반환할 수 있습니다.
std::mutex
와 달리
counting_semaphore
는 실행 스레드에 묶이지 않습니다 - 예를 들어 세마포어 획득은 세마포어 해제와 다른 스레드에서 발생할 수 있습니다.
counting_semaphore
의 모든 연산은 특정 실행 스레드와의 관계 없이 동시에 수행될 수 있으며, 소멸자는 동시에 수행될 수 없지만 다른 스레드에서 수행될 수 있다는 점이 예외입니다.
세마포어는 상호 배제보다는 신호/알림 의미론을 위해 자주 사용되며, 세마포어를 0 으로 초기화하여 acquire() 를 시도하는 수신자들을 차단한 후, 통지자가 release ( n ) 를 호출하여 "신호"를 보내는 방식으로 동작합니다. 이러한 측면에서 세마포어는 std::condition_variable 의 대안으로 간주될 수 있으며, 종종 더 나은 성능을 보입니다.
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_lib_semaphore
|
201907L
|
(C++20) |
std::counting_semaphore
,
std::binary_semaphore
|
예제
#include <chrono> #include <iostream> #include <semaphore> #include <thread> // 전역 바이너리 세마포어 인스턴스 // 객체 카운트는 0으로 설정됨 // 객체는 비신호 상태임 std::binary_semaphore smphSignalMainToThread{0}, smphSignalThreadToMain{0}; void ThreadProc() { // 메인 프로세스로부터 신호 대기 // 세마포어 감소 시도 smphSignalMainToThread.acquire(); // 이 호출은 세마포어 카운트가 메인 프로세스에서 // 증가할 때까지 블록됨 std::cout << "[thread] Got the signal\n"; // 응답 메시지 // 스레드에서 작업을 모방하기 위해 3초간 대기 // 스레드에 의한 작업 수행 using namespace std::literals; std::this_thread::sleep_for(3s); std::cout << "[thread] Send the signal\n"; // 메시지 // 메인 프로세스에 다시 신호 전송 smphSignalThreadToMain.release(); } int main() { // 작업자 스레드 생성 std::thread thrWorker(ThreadProc); std::cout << "[main] Send the signal\n"; // 메시지 // 작업자 스레드에 작업 시작 신호 전송 // 세마포어 카운트 증가 smphSignalMainToThread.release(); // 작업자 스레드가 작업을 완료할 때까지 대기 // 세마포어 카운트 감소 시도 smphSignalThreadToMain.acquire(); std::cout << "[main] Got the signal\n"; // 응답 메시지 thrWorker.join(); }
출력:
[main] Send the signal [thread] Got the signal [thread] Send the signal [main] Got the signal