讲师中心 微信公众号
AI工具推荐 视频效率加速

C++ std::counting_semaphore _ C++20原生信号量用法【实战】

浅浩君_7960

浅浩君_7960

发布时间:2026-04-13 19:38:56

|

369人浏览过

|

来源于php中文网

原创

std::counting_semaphore是C++20无锁计数信号量,初始化值须为≥0的编译期常量;acquire/release可跨线程调用,需防死锁、加超时、勿误用binary_semaphore别名,且不保证唤醒顺序。

c++ std::counting_semaphore _ c++20原生信号量用法【实战】

std::counting_semaphore 是 C++20 原生、轻量、无锁的计数信号量,但不是万能互斥替代品,用错场景或参数会直接编译失败或逻辑死锁。

初始化值必须非负,且是编译期常量

构造 std::counting_semaphore 时传入的初始值必须是 ≥ 0 的字面量或 constexpr 表达式。传负数、变量、运行时计算值都会触发编译错误,比如:

  • std::counting_semaphore sem(-1); → 编译失败:“non-negative value required”
  • int n = 3; std::counting_semaphore sem(n); → 编译失败:模板参数需为常量表达式
  • 正确写法:std::counting_semaphore sem(3); 或 constexpr int init = 2; std::counting_semaphore sem(init);

注意:模板参数(如 )是最大允许计数值,不是初始值;初始值由构造函数参数指定,且不能超过该上限。

acquire() 和 release() 不必成对出现在同一线程

这是信号量区别于 std::mutex 的关键设计。你完全可以在线程 A 中调用 release(),在线程 B 中调用 acquire() —— 它们通过共享的计数器通信,而非所有权。

立即学习“C++免费学习笔记(深入)”;

  • 典型误用:acquire() 后忘记 release() → 计数器持续为 0,其他线程永久阻塞
  • 反模式:acquire() 和 release() 在同一线程内“配对”使用,却未配合临界区保护 → 失去同步意义
  • 正确解耦场景:生产者线程 release() 通知有新数据,消费者线程 acquire() 等待数据就绪

尤其注意:没有“自动 RAII 封装”,必须手动确保 release() 被执行(比如用 std::scoped_lock 思路自己封装,或配合 try_acquire_for() 防死锁)。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

超时获取必须用 try_acquire_for() 或 try_acquire_until()

acquire() 是无条件阻塞的,一旦等待对象永远不 release(),线程就卡死。真实系统中必须加超时防护。

  • sem.try_acquire_for(std::chrono::milliseconds(500)):最多等 500ms,返回 bool
  • sem.try_acquire_until(std::chrono::steady_clock::now() + std::chrono::seconds(2)):等至绝对时间点
  • 不要试图用 while(!sem.try_acquire()) std::this_thread::yield(); 轮询 —— 浪费 CPU,且不保证唤醒时机

注意:try_acquire()(无超时)只是立即返回成功/失败,不等待;它适合纯非阻塞路径,比如事件驱动中的快速试探。

binary_semaphore 是 counting_semaphore 的别名,别混用模板参数

std::binary_semaphore 是类型别名,等价于 std::counting_semaphore。但它不接受构造参数以外的模板参数 —— 下面写法全错:

  • std::binary_semaphore sem(1); → 编译错误:“binary_semaphore is not a template”
  • std::counting_semaphore sem(0); ✅ 正确,但和 std::binary_semaphore sem(0); 等价
  • 想限制“最多 N 个并发”,必须用 std::counting_semaphore<n></n>,而不是 binary_semaphore

混淆这点会导致编译器报错“counting_semaphore is not a member of std”,尤其是旧编译器未启用 C++20 或遗漏 #include <semaphore> 时,错误信息容易误导人去查模板参数而非编译环境。

最易被忽略的一点:信号量不保证唤醒顺序。多个线程同时在 acquire() 等待时,谁先被唤醒由实现决定(通常是 FIFO,但标准不保证),若业务逻辑依赖严格调度顺序(如 ABC 打印),必须靠多个信号量接力控制,单靠一个信号量无法实现。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6124

2023.10.24

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6519

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3165

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4068

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2805

2025.08.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4278

2023.08.10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn