名前空間
変種
操作

std::counting_semaphore, std::binary_semaphore

From cppreference.com
< cpp‎ | thread
 
 
並行性サポートライブラリ
スレッド
(C++11)
(C++20)
this_thread 名前空間
(C++11)
(C++11)
(C++11)
協調的なキャンセル
排他制御
(C++11)
汎用ロック管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
条件変数
(C++11)
セマフォ
counting_semaphorebinary_semaphore
(C++20)(C++20)
ラッチとバリア
(C++20)
(C++20)
future
(C++11)
(C++11)
(C++11)
(C++11)
安全なメモリ解放 (Safe Reclamation)
(C++26)
ハザードポインタ
アトミック型
(C++11)
(C++20)
アトミック型の初期化
(C++11)(C++20で非推奨)
(C++11)(C++20で非推奨)
メモリオーダー
(C++11)(C++26で非推奨)
アトミック操作のためのフリー関数
アトミックフラグのためのフリー関数
 
 
ヘッダー<semaphore>で定義
template< std::ptrdiff_t LeastMaxValue = /* 実装定義 */ >
class counting_semaphore;
(1) (C++20以降)
using binary_semaphore = std::counting_semaphore<1>;
(2) (C++20以降)
1) counting_semaphore は、共有リソースへのアクセスを制御できる軽量な同期プリミティブです。std::mutexとは異なり、counting_semaphore は、少なくとも LeastMaxValue の同時アクセス者に対して、同じリソースへの複数の同時アクセスを許可します。LeastMaxValue が負の場合、プログラムは不正です。
2) binary_semaphore は、LeastMaxValue1 である std::counting_semaphore の特殊化のエイリアスです。実装によっては、binary_semaphorestd::counting_semaphore のデフォルト実装よりも効率的に実装できます。

counting_semaphore は、コンストラクタによって初期化される内部カウンタを保持します。このカウンタは、acquire() および関連メソッドの呼び出しによってデクリメントされ、release() の呼び出しによってインクリメントされます。カウンタがゼロの場合、acquire() はカウンタがインクリメントされるまでブロックしますが、try_acquire() はブロックしません。try_acquire_for() および try_acquire_until() は、カウンタがインクリメントされるかタイムアウトに達するまでブロックします。

std::condition_variable::wait() と同様に、counting_semaphoretry_acquire() は偶発的に失敗する可能性があります。

std::counting_semaphore の特殊化は、DefaultConstructibleCopyConstructibleMoveConstructibleCopyAssignable、または MoveAssignable ではありません。

目次

[編集] データメンバ

メンバ名 定義
counter (private) std::ptrdiff_t の内部カウンタ。
(説明用のメンバオブジェクト*)

[編集] メンバ関数

counting_semaphore を構築する
(public メンバ関数) [編集]
counting_semaphore を破棄する
(public メンバ関数) [編集]
operator=
[削除]
counting_semaphore は代入不可
(public メンバ関数) [編集]
操作
内部カウンタをインクリメントし、アクライアをブロック解除する
(public メンバ関数) [編集]
内部カウンタをデクリメントするか、デクリメントできるまでブロックする
(public メンバ関数) [編集]
ブロックせずに内部カウンタをデクリメントしようとする
(public メンバ関数) [編集]
内部カウンタをデクリメントしようと試み、duration 時間までブロックする
(public メンバ関数) [編集]
内部カウンタをデクリメントしようと試み、特定の時点までブロックする
(public メンバ関数) [編集]
定数
[static]
内部カウンタの最大可能値を返す
(public static メンバ関数) [編集]

[編集] 注釈

その名前が示すように、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>
 
// global binary semaphore instances
// object counts are set to zero
// objects are in non-signaled state
std::binary_semaphore
    smphSignalMainToThread{0},
    smphSignalThreadToMain{0};
 
void ThreadProc()
{
    // wait for a signal from the main proc
    // by attempting to decrement the semaphore
    smphSignalMainToThread.acquire();
 
    // this call blocks until the semaphore's count
    // is increased from the main proc
 
    std::cout << "[thread] Got the signal\n"; // response message
 
    // wait for 3 seconds to imitate some work
    // being done by the thread
    using namespace std::literals;
    std::this_thread::sleep_for(3s);
 
    std::cout << "[thread] Send the signal\n"; // message
 
    // signal the main proc back
    smphSignalThreadToMain.release();
}
 
int main()
{
    // create some worker thread
    std::thread thrWorker(ThreadProc);
 
    std::cout << "[main] Send the signal\n"; // message
 
    // signal the worker thread to start working
    // by increasing the semaphore's count
    smphSignalMainToThread.release();
 
    // wait until the worker thread is done doing the work
    // by attempting to decrement the semaphore's count
    smphSignalThreadToMain.acquire();
 
    std::cout << "[main] Got the signal\n"; // response message
    thrWorker.join();
}

出力

[main] Send the signal
[thread] Got the signal
[thread] Send the signal
[main] Got the signal
English 日本語 中文(简体) 中文(繁體)