C++20中的counting_semaphore的应用

一、std::counting_semaphore

在前面介绍过C++20中的同步库,其中就提到过std::counting_semaphore。但当时的重点是同步库的整体介绍,本文则会对std::counting_semaphore这个信号量进行一个全面的分析和说明,并有针对性的给出具体的例程。
C++20中对其的定义为:

template< std::ptrdiff_t LeastMaxValue = /* implementation-defined */ >
class counting_semaphore;
using binary_semaphore = std::counting_semaphore<1>;

LeastMaxValue值并不实际最大值,即此值是可以被突破的。

二、应用说明

要想掌握好std::counting_semaphore,如果能够在学习操作系统时将其中的PV原语理解的很透彻,那么这就不是什么问题了。所以推荐大家如果不清楚的可以回头先看一看什么是PV原语。
std::counting_semaphore作为一个轻量级的同步原语,主要是用来对共享资源的控制,与互斥体等的不同,其允许对同一资源进行指定数量的线程同步访问。怎么说呢,其实就是C++标准中的同步控制,在以前基本只能同一情况下访问同一资源(其它库如Posix,windows平台等)。可能大牛们觉得已经够用了,但在其它语言都推出了信号灯及其类似的同步原语,而且随着C++应用的不断发展,应该是大牛们觉得还是要提供一下类似的实现(这只是个人猜测)。
counting_semaphore提供了一个指定线程同步访问的数量,而binary_semaphore则可以理解成前者的一个特化例子,只支持0,1两种状态,有点类似于互斥体,但它没有所有权一说。这样应用到一些特定的场景时不用调用复杂的counting_semaphore。
std::counting_semaphore与普通的Mutex一个重要的不同在于,与线程的所有权控制不同,前者不会绑定到指定的线程,也即任何一个线程都可以进行获取和释放信号量,请开发者一定要明白。
其最典型的两个接口为:
1、std::counting_semaphore::release
原子性的按Update增加内部计数器,即增加信号量。当然update的值需要大于等0且小于等于最大值-当前计数器大小。
2、std::counting_semaphore::acquire
原子性的将内部计数器减1,前提是内部计数器大于0;否则将阻塞线程,直到计数器超过0。

这里有一个需要注意的情况,counting_semaphore在信号的下限即0时,调用acquire,不会出现异常问题;但在到达上限时,再调用release,则会出现UB行为。这点非常重要。
如果大家想扩展一下视野,还可以看看其它库或平台中的类似的semaphore的实现,也可以看看其它语言(如Java等)中类似的实现,就可以更好的理解信号量的应用。

三、例程

看一下cppreference上的例程:

#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_semaphoresmphSignalMainToThread{0},smphSignalThreadToMain{0};void ThreadProc()
{// wait for a signal from the main proc// by attempting to decrement the semaphoresmphSignalMainToThread.acquire();// this call blocks until the semaphore's count// is increased from the main procstd::cout << "[thread] Got the signal\n"; // response message// wait for 3 seconds to imitate some work// being done by the threadusing namespace std::literals;std::this_thread::sleep_for(3s);std::cout << "[thread] Send the signal\n"; // message// signal the main proc backsmphSignalThreadToMain.release();
}int main()
{// create some worker threadstd::thread thrWorker(ThreadProc);std::cout << "[main] Send the signal\n"; // message// signal the worker thread to start working// by increasing the semaphore's countsmphSignalMainToThread.release();// wait until the worker thread is done doing the work// by attempting to decrement the semaphore's countsmphSignalThreadToMain.acquire();std::cout << "[main] Got the signal\n"; // response messagethrWorker.join();
}

运行结果:

[main] Send the signal
[thread] Got the signal
[thread] Send the signal
[main] Got the signal

四、总结

大牛陈硕曾经说过,实际的编程场景基本用不到semaphore,如果真用到了,极有可能设计上有问题。他的这个说法本人非常赞同。建议在实际场景中尽量还是谨慎使用这种信号量,不过,在某些特定的场景下,如果确实是需要使用信号量,或者整体考虑代价要小于其它方法的情况下,也不是不可以使用。
仍然是前面反复提到的,合适的就是最好的。技术本身没有绝对的好与坏!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87784.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87784.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mongo常用命令

1 连接mongo服务器 mongo ip:端口/库名 -u 用户名 -p 密码 2 选择数据库 show dbs; 显示数据库列表 use 数据库名称; 3 集合操作 &#xff08;1&#xff09; 显示集合列表 show tables; &#xff08;2&#xff09;删除集合 db.集合名称.drop(); &#xff08;3&#x…

华为云 银河麒麟 vscode远程连接

解决方案 检查 SSH 服务器配置&#xff1a; 在远程主机上编辑 /etc/ssh/sshd_config 文件 关键配置说明&#xff1a; AllowTcpForwarding yes # 允许TCP端口转发&#xff08;必须开启&#xff09; AllowAgentForwarding yes # 允许SSH代理转发&#xff08;可选&#xf…

有限状态机(Finite State Machine)

文章目录有限状态机&#xff08;Finite State Machine&#xff09;简介状态机的组成六要素(1) 状态集合(2) 初态(3) 终态(4) 输入符号集(5) 输出符号集(6) 状态转移函数状态机的工作四要素(1) 现态(2) 输入(3) 输出(4) 次态FPGA中的状态机模型1. Moore型状态机(1) Moore l型(2)…

前端框架中注释占位与Fragment内容替换的实现与优化

在现代前端开发中&#xff0c;使用注释占位符替换Fragment内容是一种常见的需求&#xff0c;尤其在处理动态内容、模板预加载和组件复用场景中。React和Vue作为当前最主流的前端框架&#xff0c;提供了不同的实现方式和优化策略&#xff0c;但核心目标都是减少不必要的DOM操作&…

uniapp中使用web-worker性能优化的分享

为什么要使用 web-workers原因很简单&#xff0c;将复杂的计算逻辑和耗时逻辑放到线程中运行&#xff0c;避免ui阻塞&#xff0c;防止卡顿问题场景&#xff1a;本次运用于GPS 位置更新接入小程序注意事项&#xff1a;微信小程序中只允许存在一个 worker所以&#xff0c;需要再一…

5118 API智能处理采集数据教程

简数采集器支持调用5118 API接口处理采集的数据标题和内容、关键词、描述等&#xff0c;还可配合简数采集的SEO功能优化文章数据&#xff0c;对提高收录有积极的作用。 简数采集器支持5118接口&#xff1a;5118智能核心词提取API 和 5118智能摘要提取API 。 接入使用教程 1. …

【深度学习:进阶篇】--4.2.词嵌入和NLP

在RNN中词使用one_hot表示的问题 假设有10000个词 每个词的向量长度都为10000&#xff0c;整体大小太大 没能表示出词与词之间的关系 例如Apple与Orange会更近一些&#xff0c;Man与Woman会近一些&#xff0c;取任意两个向量计算内积都为0 目录 1.词嵌入 1.1.特点 1.3.wor…

WebRTC 的 ICE candidate 协商

文章目录 前言WebRTC 的 ICE candidate 协商1. 什么是 ICE candidate&#xff1f;2. ICE 协商的流程3.前端使用 ICE candidate 协商代码示例1&#xff09;收集 candidate 并发送2&#xff09;WebSocket 接收 candidate 并添加 4. ICE candidate 的类型5. ICE 协商常见问题6. 关…

卡尔曼滤波介绍

卡尔曼滤波介绍&#x1f4d6; **卡尔曼滤波原理简介**&#x1f511; **核心思想**&#x1f4e6; **卡尔曼滤波的组成**&#x1f50d; **代码分析&#xff08;kalman_filter.py&#xff09;**&#x1f3d7;️ 1. 状态空间定义&#x1f504; 2. 初始化模型矩阵&#x1f680; 3. 核…

递归与循环

文章目录递归TestRecursiveListRemoveNodeTestRecursiveListRemoveNode2循环TestWhileLoopListRemoveNodeTestWhileLoopListRemoveNode2递归 关键理解这几点&#xff1a; 1、求解基本问题 2、将原问题拆分为小问题&#xff0c;直至基本问题&#xff08;难点&#xff09; 3、借…

3D魔方游戏

# 3D魔方游戏 这是一个基于Three.js的3D魔方游戏&#xff0c;支持2到6阶魔方的模拟操作。 ## 功能特点 - 支持2到6阶魔方 - 真实的3D渲染效果 - 鼠标操作控制 - 随机打乱功能 - 提示功能 - 重置功能 ### 安装依赖 bash npm install ### 启动游戏 bash npm start 然…

下载安装 com0com

下载 在 sourceforge 网站下载安装器&#xff1a;下载链接 安装完成后可以在设备管理器中看到默认创建的一对虚拟串口 使用串口调试助手收发 使用串口调试助手分别打开。如下图所示&#xff0c;在端口选择的下拉列表中可以看到刚才在设备管理器中看到的 COM3 和 COM5 分…

C++ 应用软件开发从入门到实战详解

目录 1、引言 2、IDE 开发环境介绍 2.1、Visual Studio 2.2、Qt Creator 3、 C语言特性 3.1、熟悉泛型编程 3.2、了解C/C异常处理 3.3、熟练使用STL容器 3.4、熟悉C11新特性 4、Windows 平台的编程技术与调试技能 4.1、需要掌握的若干编程技术和基础知识 4.2、需…

Python爬虫实战:研究slug相关技术

1. 引言 1.1 研究背景与意义 随着互联网技术的快速发展,网络上的信息量呈爆炸式增长。如何从海量的非结构化数据中提取有价值的信息,成为当前数据科学领域的重要研究方向。网络爬虫作为一种自动化数据采集工具,可以高效地获取网页内容,为数据分析提供丰富的数据来源。 Sl…

人工智能-基础篇-18-什么是RAG(检索增强生成:知识库+向量化技术+大语言模型LLM整合的技术框架)

RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09;是一种结合外部知识检索与大语言模型&#xff08;LLM&#xff09;生成能力的技术框架&#xff0c;旨在提升生成式AI在问答、内容创作等任务中的准确性、实时性和领域适应性。 1、核心概念 …

CppCon 2018 学习:What do you mean “thread-safe“

什么是“线程安全”&#xff1f; “线程安全”指的是一个函数、方法或代码块能够在多个线程同时执行时&#xff0c;不会出现意外的交互或破坏共享数据&#xff0c;能够安全地运行。 POSIX 对线程安全的定义很清楚&#xff1a; “一个线程安全的函数可以在多个线程中被安全地并…

热方程初边值问题解法

已知公式&#xff1a; u ( x , t ) ∫ − ∞ ∞ G ( x , y , t ) g ( y ) d y . u(x,t)\int_{-\infty}^{\infty}G(x,y,t)g(y)dy. u(x,t)∫−∞∞​G(x,y,t)g(y)dy. &#xff08;1&#xff09; 其中 G ( x , y , t ) 1 2 k π t e − ( x − y ) 2 4 k t G(x,y,t)\frac{1}{2…

怎样理解:source ~/.bash_profile

场景复现 $ source ~/.bash_profileAnalysis 分析 一句话概括 source ~/.bash_profile “在 当前 终端会话里&#xff0c;立刻执行并加载 ~/.bash_profile 中的所有命令&#xff0c;让其中定义的环境变量、函数、alias 等即时生效&#xff0c;而无需重新登录或开新 Shell。…

搜索问答技术概述:基于知识图谱与MRC的创新应用

目录 一、问答系统应用分析 二、搜索问答技术与系统 &#xff08;一&#xff09;需求和信息分析 问答需求类型 多样的数据源 文本组织形态 &#xff08;二&#xff09;主要问答技术介绍 发展和成熟度分析 重点问答技术基础&#xff1a;KBQA和DeepQA KBQA&#xff08;…

TCP数据的发送和接收

本篇文章结合实验对 TCP 数据传输中的重传机制、滑动窗口以及拥塞控制做简要的分析学习。 重传 实验环境 这里使用两台腾讯云服务器&#xff1a;vm-1&#xff08;172.19.0.3&#xff09;和vm-2&#xff08;172.19.0.6&#xff09;。 超时重传 首先 vm-1 作为服务端启动 nc…