본문 바로가기
Language/C++

[C++] std::semaphore

by 어발 2025. 10. 27.
std::semaphore
- C++20 에서 추가됨
- 자원에 대한 한정적인 공유 (N개의 쓰레드가 공유)
- <semaphore> 헤더

 

std::counting_semaphore

std::counting_semaphore<MAX_COUNT> sem(counter 초기값);

counter의 조건
  0 <= counter <= MAX_COUNT

sem.counter + update > MAX_COUNT라면 std::system_error
#include <iostream>
#include <thread>
#include <string>
#include <chrono>
#include <semaphore>
using namespace std::literals;

std::counting_semaphore<3> sem(3);

void Download(std::string name) {
    sem.acquire();	// --sem.counter;
    
    for (int i = 0; i < 100 ; i++) {
        std::cout << name;
        std::this_thread::sleep_for(30ms);
    }
    
    sem.release(); // sem.release(update=1)을 의미; sem.counter += update; 
}

int main() {
    std::thread t1(Download, "1");
    std::thread t2(Download, "2");
    std::thread t3(Download, "3");
    std::thread t4(Download, "4");
    std::thread t5(Download, "5");
    
    t1.join(), t2.join(), t3.join();
    t4.join(), t5.join();
}

 

std::mutex vs std::semaphore

mutex 자원의 독점
lock 획득한 쓰레드만 unlock 가능
semaphore 자원의 한정적인 공유
모든 쓰레드가 counter를 증가할 수 있다. 

 

아래 코드처럼 다른 쓰레드에서 counter을 증가한다면, 프로그램 시작후 2초까지는 3개의 숫자만 출력되다가 2초 후에는 5개의 숫자가 출력됨을 확인할 수 있다.

#include <iostream>
#include <thread>
#include <string>
#include <chrono>
#include <semaphore>
using namespace std::literals;

std::counting_semaphore<3> sem(3);

void Download(std::string name) {
    sem.acquire();
    
    for (int i = 0; i < 100 ; i++) {
        std::cout << name;
        std::this_thread::sleep_for(30ms);
    }
    
    sem.release();
}

int main() {
    std::thread t1(Download, "1");
    std::thread t2(Download, "2");
    std::thread t3(Download, "3");
    std::thread t4(Download, "4");
    std::thread t5(Download, "5");
    
    std::this_thread::sleep_for(2s);
    sem.release(2);
    
    t1.join(), t2.join(), t3.join();
    t4.join(), t5.join();
}

 

std::counting_semaphore<1> sem(1);
 - mutex와 동일한 의미

위 경우에는 std::binary_semaphore sem(1)을 사용하자.
using binary_semaphore = std::counting_semaphore<1>;

 

std::semaphore의 멤버 함수

acquire semaphore을 1개 감소시킨다.
try_acquire acquire을 시도하여 가능하면 true반환. 아니면 false 반환.
try_acquire_for 주어진 시간동안 acquire을 하기 위해 기다림.
try_acquire_until 주어진 시간때까지 acquire하기 위해 대기.
release 주어진 숫자만큼 counter을 증가
728x90

'Language > C++' 카테고리의 다른 글

[C++] std::condition_variable  (0) 2025.07.14
[C++] std::unique_lock, std::scope_lock, std::shared_lock  (5) 2025.07.09
[C++] std::shared_mutex  (0) 2025.07.08
[C++] std::timed_mutex, std::recursive_mutex  (1) 2025.02.03
[C++] std::jthread  (0) 2025.01.06

댓글