std::counting_semaphore 具体内容看std::counting_semaphore, std::binary_semaphore - C++中文 - API参考文档 (apiref.com)。其原理和 std::condition_variable 一样,std::counting_semaphore是它的轻量级实现。
简单的说即根据信号量(内部计数器)大于和等于零进行不同的操作,acquire 会让信号量减一,release 会让信号量加一(其它操作看参考文档,和std::condition_variable 大同小异):
- 大于零,进行 acquire 操作,信号量减一,不会堵塞线程
- 等于零,进行 acquire 操作,信号量为零,无法再减,堵塞线程,直到 release 操作让信号量加一(大于零),重复上一步
下面是循环打印代码
int main(int argc, char* argv[]) { system("chcp 65001"); std::counting_semaphore<2> sem{ 2 }; // 最大信号量为2,可用初始值为2 std::thread t1([&] { while (true) { sem.acquire(); cout << "t1\n"; } }); std::thread t2([&] { while (true) { sem.acquire(); cout << "t2\n"; } }); std::thread t3([&] { while (true) { sem.acquire(); cout << "t3\n"; } });
// t4用于不断 release 增加信号量,若通过 release 操作导致信号量比设定最大值还大,则程序崩溃 std::thread t4([&] { while (true) { std::this_thread::sleep_for(500ms); sem.release(); } }); t1.join(); t2.join(); t3.join(); t4.detach(); cout << "end\n"; return 0; }
std::binary_semaphore 是模板参数为 1 的 std::counting_semaphore 别名。