std::counting_semaphore<LeastMaxValue>:: acquire
From cppreference.net
<
cpp
|
thread
|
counting semaphore
C++
Concurrency support library
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
std::counting_semaphore
| Member functions | ||||
| Operations | ||||
|
counting_semaphore::acquire
|
||||
| Constants | ||||
|
void
acquire
(
)
;
|
(C++20부터) | |
내부 카운터가 1 보다 크면 원자적으로 내부 카운터를 감소시키고, 그렇지 않으면 내부 카운터가 0 보다 커져서 내부 카운터를 성공적으로 감소시킬 수 있을 때까지 블록합니다.
목차 |
사전 조건
(없음)
매개변수
(없음)
예외
다음을 throw할 수 있습니다 std::system_error .
예제
이 예제는 세마포어의 desired 값인 N개를 초과하지 않는 여러 무작위 스레드들이 동시에 작동하는 상황을 시각화합니다. 이때 나머지 스레드 함수들은 세마포어에서 대기 상태일 수 있습니다.
이 코드 실행
#include <array>
#include <chrono>
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <new>
#include <random>
#include <semaphore>
#include <thread>
#include <vector>
using namespace std::리터럴;
constexpr std::size_t max_threads{10U}; // 변경하고 효과 확인
constexpr std::ptrdiff_t max_sema_threads{3}; // {1} 바이너리 세마포어용
std::counting_semaphore semaphore{max_sema_threads};
constexpr auto time_tick{10ms};
unsigned rnd()
{
static std::uniform_int_distribution<unsigned> distribution{2U, 9U}; // [delays]
static std::random_device engine;
static std::mt19937 noise{engine()};
return distribution(noise);
}
class alignas(std::hardware_destructive_interference_size) Guide
{
inline static std::mutex cout_mutex;
inline static std::chrono::time_point
(번역 참고: HTML 태그와 속성은 번역하지 않았으며, C++ 관련 용어인 `std::chrono::time_point`는 원문 그대로 유지했습니다)<std::chrono::high_resolution_clock> started_at;
unsigned delay{rnd()}, occupy{rnd()}, wait_on_sema{};
public:
static void start_time() { started_at = std::chrono::high_resolution_clock::now
**변경 없음** - 모든 텍스트가 C++ 표준 라이브러리 식별자이므로 번역하지 않음(); }
void initial_delay() { std::this_thread::sleep_for(delay * time_tick); }
void occupy_sema()
{
wait_on_sema =
static_cast<unsigned>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now
**번역 결과:**
HTML 태그와 속성은 번역하지 않고 원본 형식을 유지합니다. , ,
() - started_at -
delay * time_tick).count() / time_tick.count());
std::this_thread::sleep_for(occupy * time_tick);
}
void visualize(unsigned id, unsigned x_scale = 2) const
{
auto cout_n = [=](auto str, unsigned n)
{
for (n *= x_scale; n-- > 0; std::cout << str)
;
};
std::lock_guard lk{cout_mutex};
std::cout << '#' << std::setw(2) << id << ' ';
cout_n("░", delay);
cout_n("▒", wait_on_sema);
cout_n("█", occupy);
std::cout << '\n';
}
static void show_info()
{
std::cout << "\n스레드: " << max_threads << ", 처리량: " << max_sema_threads
<< " │ 범례: 초기 지연 ░░ │ 대기 상태 ▒▒ │ 세마포어 점유 ██ \n"
<< std::endl;
}
};
std::array<Guide, max_threads> guides;
void workerThread(unsigned id)
{
guides[id].initial_delay(); // 세마포어 획득 전 일부 작업 에뮬레이션
semaphore.acquire(); // 사용 가능한 세마 슬롯이 있을 때까지 대기
guides[id].occupy_sema(); // 세마포어가 획득된 동안 일부 작업을 에뮬레이션합니다
semaphore.release();
guides[id].visualize(id);
}
int main()
{
std::vector<std::jthread> threads;
threads.reserve(max_threads);
Guide::show_info();
Guide::start_time();
for (auto id{0U}; id != max_threads; ++id)
threads.push_back(std::jthread(workerThread, id));
}
가능한 출력:
기본 케이스: max_threads{10U}, max_sema_threads{3}
스레드: 10, 처리량: 3 │ 범례: 초기 지연 ░░ │ 대기 상태 ▒▒ │ 세마포어 점유 ██
# 1 ░░░░██████
# 2 ░░░░████████
# 5 ░░░░░░██████████
# 8 ░░░░░░░░░░░░████████████
# 9 ░░░░░░░░░░░░██████████████
# 7 ░░░░░░░░░░░░▒▒▒▒████████████████
# 4 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒████████
# 6 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒██████████████████
# 3 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████████
# 0 ░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
"모두에게 충분한" 케이스 (대기 상태 없음!): max_threads{10U}, max_sema_threads{10}
스레드: 10, 처리량: 10 │ 범례: 초기 지연 ░░ │ 대기 상태 ▒▒ │ 세마포어 점유 ██
# 4 ░░░░██████
# 5 ░░░░░░████
# 3 ░░░░██████████
# 1 ░░░░██████████
# 8 ░░░░░░░░████████████
# 6 ░░░░░░░░░░░░░░░░██████
# 7 ░░░░░░░░░░░░░░░░██████
# 9 ░░░░░░░░░░░░░░░░██████████
# 0 ░░░░░░░░░░░░██████████████████
# 2 ░░░░░░░░░░░░░░░░░░████████████
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
이진 세마포어 케이스: max_threads{10U}, max_sema_threads{1}
스레드: 10, 처리량: 1 │ 범례: 초기 지연 ░░ │ 대기 상태 ▒▒ │ 세마포어 점유 ██
# 6 ░░░░████
# 5 ░░░░▒▒▒▒████
# 4 ░░░░░░░░░░▒▒██████████
# 7 ░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒████████████████
# 2 ░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████
# 3 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████████████
# 0 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████████
# 1 ░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████
# 8 ░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████
# 9 ░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████
참고 항목
|
내부 카운터를 증가시키고 획득자들의 차단을 해제합니다
(public member function) |
|
|
내부 카운터를 차단 없이 감소시키려 시도합니다
(public member function) |
|
|
내부 카운터를 감소시키려 시도하며, 최대 지정 시간 동안 차단합니다
(public member function) |
|
|
내부 카운터를 감소시키려 시도하며, 특정 시점까지 차단합니다
(public member function) |