std::counting_semaphore, std::binary_semaphore

来自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)
信号量
counting_semaphorebinary_semaphore
(C++20)(C++20)
闩与屏障
(C++20)
(C++20)
未来体
(C++11)
(C++11)
(C++11)
安全回收
风险指针
原子类型
(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::mutexcounting_semaphore 允许同一资源进行多个并发的访问,至少允许 LeastMaxValue 个同时的访问者。若 LeastMaxValue 为负则程序非良构。
2)binary_semaphorestd::counting_semaphore 的特化的别名,其 LeastMaxValue1。实现可能将 binary_semaphore 实现得比 std::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 的特化不满足可默认构造(DefaultConstructible) 可复制构造(CopyConstructible) 可移动构造(MoveConstructible) 可复制赋值(CopyAssignable) 可移动赋值(MoveAssignable)

目录

[编辑]数据成员

成员名 定义
counter(私有)std::ptrdiff_t 类型的内部计数器。
(仅用于阐述的成员对象*)

[编辑]成员函数

构造 counting_semaphore
(公开成员函数)[编辑]
销毁 counting_semaphore
(公开成员函数)[编辑]
operator=
[弃置]
counting_semaphore 不可赋值
(公开成员函数)[编辑]
操作
增加内部计数器并解除获得者
(公开成员函数)[编辑]
减少内部计数器或阻塞到直至能如此
(公开成员函数)[编辑]
尝试减少内部计数器而不阻塞
(公开成员函数)[编辑]
尝试减少内部计数器,阻塞至多一段时长
(公开成员函数)[编辑]
尝试减少内部计数器,阻塞直至一个时间点
(公开成员函数)[编辑]
常量
[静态]
返回内部计数器的最大可能值
(公开静态成员函数)[编辑]

[编辑]注解

如其名所示,LeastMaxValue最小 的最大值,而非实际 最大值。因此 max() 能产生大于 LeastMaxValue 的值。

不同于 std::mutexcounting_semaphore 不与执行线程捆绑——例如,能在不同于释放信号量的线程获取该信号量。能同时进行 counting_semaphore 上的所有操作而无需联系到任何特定的执行线程,但析构函数能在一个不同的线程上执行但不能在多个线程同时执行。

信号量常用于发信/提醒而非互斥,通过初始化该信号量为 0 从而阻塞尝试 acquire() 的接收者,直至提醒者通过调用 release(n) “发信”。在此方面可把信号量当作 std::condition_variable 的代用品,通常它有更好的性能。

功能特性测试标准功能特性
__cpp_lib_semaphore201907L(C++20)std::counting_semaphore, std::binary_semaphore

[编辑]示例

#include <chrono>#include <iostream>#include <semaphore>#include <thread>   // 全局二元信号量实例// 设置对象计数为零// 对象处于未被发信状态 std::binary_semaphore smphSignalMainToThread{0}; std::binary_semaphore smphSignalThreadToMain{0};   void ThreadProc(){// 通过尝试减少信号量的计数等待来自主程序的信号 smphSignalMainToThread.acquire();   // 此调用阻塞直至信号量的计数被从主程序增加   std::cout<<"[线程] 获得信号"<<std::endl;// 回应消息   // 等待 3 秒以模拟某种线程正在进行的工作usingnamespace std::literals;std::this_thread::sleep_for(3s);   std::cout<<"[线程] 发送信号\n";// 消息   // 对主程序回复发信 smphSignalThreadToMain.release();}   int main(){// 创建某个工作线程std::thread thrWorker(ThreadProc);   std::cout<<"[主] 发送信号\n";// 消息   // 通过增加信号量的计数对工作线程发信以开始工作 smphSignalMainToThread.release();   // 通过试图减少信号量的计数等待直至工作线程完成工作 smphSignalThreadToMain.acquire();   std::cout<<"[主] 获得信号\n";// 回应消息 thrWorker.join();}

输出:

[主] 发送信号 [线程] 获得信号 [线程] 发送信号 [主] 获得信号
close