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
英文地址,請注明出處:http://en.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…