C++ 20 信號量詳解

C++ 20 信號量詳解

一、信號量類型

C++20 標準中定義了兩種信號量:

  1. std::counting_semaphore<Max>:計數信號量(允許資源池最多有 Max 個資源)
  2. std::binary_semaphore:二進制信號量(等價于 std::counting_semaphore<1>

二、代碼實現與詳解
1. 計數信號量(生產者-消費者模型)
#include <iostream>
#include <thread>
#include <semaphore>
#include <queue>
#include <mutex>// 最大緩沖區大小
constexpr size_t BUFFER_SIZE = 5;// 定義信號量(空位初始為5,數據初始為0)
std::counting_semaphore<BUFFER_SIZE> empty_slots(BUFFER_SIZE);
std::counting_semaphore<BUFFER_SIZE> data_items(0);std::mutex mtx;              // 保護共享隊列的互斥鎖
std::queue<int> buffer;       // 共享緩沖區
bool producer_done = false;  // 生產完成標志void producer() {for (int i = 1; i <= 10; ++i) {empty_slots.acquire(); // 等待空位{std::lock_guard<std::mutex> lock(mtx);buffer.push(i);std::cout << "Product: " << i << std::endl;}data_items.release(); // 增加數據項}// 生產完成后設置標志std::lock_guard<std::mutex> lock(mtx);producer_done = true;
}void consumer() {while (true) {data_items.acquire(); // 等待數據{std::lock_guard<std::mutex> lock(mtx);// 檢查是否所有數據已消費if (producer_done && buffer.empty()) break;int val = buffer.front();buffer.pop();std::cout << "Consume: " << val << std::endl;}empty_slots.release(); // 釋放空位}
}int main() {std::jthread prod(producer); // C++20 自動管理線程std::jthread cons(consumer);return 0;
}
2. 二進制信號量(互斥訪問)
#include <iostream>
#include <thread>
#include <semaphore>std::binary_semaphore resource(1);  // 初始可用
int counter = 0;void worker(int id) {for (int i = 0; i < 3; ++i) {resource.acquire();  // P操作++counter;std::cout << "線程" << id << "修改計數器: " << counter << std::endl;resource.release();  // V操作std::this_thread::sleep_for(std::chrono::milliseconds(100));}
}int main() {std::jthread t1(worker, 1);std::thread t2(worker, 2);t1.join();t2.join();return 0;
}

三、編譯與運行
  1. 編譯命令(需要支持C++20的編譯器):

    g++ -std=c++20 -pthread -o semaphore_demo semaphore_demo.cpp
    
  2. 輸出示例
    在這里插入圖片描述


四、核心概念解析
  1. acquire()(P操作):

    • 減少信號量計數器
    • 若計數器為0則阻塞,直到有其他線程執行release()
  2. release()(V操作):

    • 增加信號量計數器
    • 喚醒等待中的線程(如果有)
  3. 二進制信號量特性

    • 初始值設為1時等價于互斥鎖
    • 但釋放操作可由任意線程執行(與互斥鎖不同)

五、關鍵點總結
特性計數信號量二進制信號量
最大計數值模板參數指定(如<5>固定為1
典型應用場景資源池管理互斥訪問/同步標志
線程喚醒策略先進先出(FIFO)取決于具體實現
內存占用每個實例約4-8字節同計數信號量

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/79545.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79545.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/79545.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue3中provide和inject的用法示例

在 Vue3 中&#xff0c;provide 和 inject 用于實現跨層級組件通信。以下是一個簡單的示例&#xff1a; 1. 父組件 (祖先組件) - 提供數據 javascript 復制 // ParentComponent.vue import { provide, ref, reactive } from vue;export default {setup() {// 提供靜態數據p…

Spring數據訪問全解析:ORM整合與JDBC高效實踐

目錄 一、Spring ORM集成深度剖析 &#x1f31f; ORM模塊架構設計 核心集成特性&#xff1a; 整合MyBatis示例配置&#xff1a; 二、Spring JDBC高效實踐指南 &#x1f31f; 傳統JDBC vs Spring JDBC對比 &#x1f31f; JdbcTemplate核心操作示例 批量操作優化&#xf…

UE快速預覽材質節點快捷鍵

開始預覽節點 添加快捷鍵 然后按R就能快速預覽 不用再右鍵了 非常方便

Java漏洞原理與實戰

一、基本概念 1、序列化與反序列化 (1)序列化:將對象寫入IO流中&#xff0c;ObjectOutputStream類的writeobject()方法可以實現序列化 (2)反序列化:從IO流中恢復對象&#xff0c;ObjectinputStream類的readObject()方法用于反序列化 (3)意義:序列化機制允許將實現序列化的J…

每日算法【雙指針算法】(Day 1-移動零)

雙指針算法 1.算法題目&#xff08;移動零&#xff09;2.講解算法原理3.編寫代碼 1.算法題目&#xff08;移動零&#xff09; 2.講解算法原理 數組劃分&#xff0c;數組分塊&#xff08;快排里面最核心的一步&#xff09;只需把0改為tmp 雙指針算法&#xff1a;利用數組下標來…

SQL Server 的鎖機制

SQL Server 的鎖機制是為了確保數據的一致性和事務的隔離性而設計的。以下是針對讀寫操作的鎖定行為的詳細說明&#xff1a; 1. 鎖的基本類型 SQL Server 的鎖主要分為以下幾類&#xff1a; 共享鎖&#xff08;Shared Lock, S Lock&#xff09; 用於讀操作&#xff08;如 S…

AIP目錄

專注于開發靈活API的設計文檔。 AIP是總結了谷歌API設計決策的設計文檔&#xff0c;它也為其他人提供了用文檔記錄API設計規則和實踐的框架和系統。 基礎1AIP目的和指南2AIP編號規則3AIP版本管理200先例8AIP風格與指導9術語表流程100API設計評審常見問題205Beta版本發布前置條…

CSS進度條帶斑馬紋動畫(有效果圖)

效果圖 .wxml <view class"tb"><view class"tb-line" style"transform:translateX({{w%}})" /> </view> <button bind:tap"updateLine">增加進度</button>.js Page({data: {w:0,},updateLine(){this.…

【工具-Krillin AI】視頻翻譯、配音、語音克隆于一體的一站式視頻多語言轉換工具~

Krillin AI 是全能型音視頻本地化與增強解決工具。這款簡約而強大的工具&#xff0c;集音視頻翻譯、配音、語音克隆于一身&#xff0c;支持橫豎屏格式輸出&#xff0c;確保在所有主流平臺&#xff08;嗶哩嗶哩&#xff0c;小紅書&#xff0c;抖音&#xff0c;視頻號&#xff0c…

zset.

zset 有序集合 zset 保留了 set 不能有重復元素的特點 zset 中的每個元素都有一個唯一的浮點類型的分數&#xff08;score&#xff09;與之關聯&#xff0c;使得 zset 內部的元素是可以維護有序性的。但是這個有序不是用下標作為排序依據的&#xff0c;而是根據分數&#xf…

Spring 數據庫編程

Spring JDBC 傳統的JDBC在操作數據庫時&#xff0c;需要先打開數據庫連接&#xff0c;執行SQL語句&#xff0c;然后封裝結果&#xff0c;最后關閉數據庫連接等資源。頻繁的數據庫操作會產生大量的重復代碼&#xff0c;造成代碼冗余&#xff0c;Spring的JDBC模塊負責數據庫資源…

492Q 型氣缸蓋雙端面銑削組合銑床總體設計

一、引言 492Q 型氣缸蓋是發動機的重要組成部分&#xff0c;其雙端面的加工精度對發動機的性能和可靠性有著重要影響。設計一款適用于 492Q 型氣缸蓋雙端面銑削的組合銑床&#xff0c;能夠提高加工效率和質量&#xff0c;滿足發動機生產的需求。 二、總體設計要求 加工精度&…

顎式破碎機的設計

一、引言 顎式破碎機作為礦山、建材等行業的重要破碎設備&#xff0c;其性能優劣直接影響物料破碎效率與質量。隨著工業生產規模的擴大和對破碎效率要求的提高&#xff0c;設計一款高效、穩定、節能的顎式破碎機具有重要意義。 二、設計需求分析 處理能力&#xff1a;根據目…

第三階段面試題

Nginx nginx常用模塊以及其功能 proxy模塊&#xff0c;進行代理功能 ssl模塊&#xff0c;進行HTTPS協議的使用 gzip模塊&#xff0c;進行傳輸數據的壓縮 upstream模塊&#xff0c;進行反向代理時使用 static模塊&#xff0c;靜態資源進行訪問的模塊 cache模塊&#xff0…

鴻蒙NEXT開發鍵盤工具類(ArkTs)

export declare type KeyboardCallBack (show: boolean, height: number) > void; import { AppUtil } from ./AppUtil; import { LogUtil } from ./LogUtil; import { ArrayUtil } from ./ArrayUtil;/*** 鍵盤工具類* author 鴻蒙布道師* since 2025/04/18*/ export class…

基于 LabVIEW 的電液伺服閥測試臺開發

開發了一種基于 LabVIEW 圖形編程語言的自動測試系統&#xff0c;能夠完成電液伺服閥的空載流量特性、壓力增益特性、內泄漏特性等靜態特性的自動測試。針對測試過程中干擾信號頻段與正常信號頻段接近&#xff0c;普通數字濾波器濾波效果不佳的問題&#xff0c;采用迭代濾波分解…

【uniapp】vue2 使用 Vuex 狀態管理

創建store文件夾&#xff1a;store/index.js // index.js import Vue from vue import Vuex from vuex import address from ./modules/address.jsVue.use(Vuex)const store new Vuex.Store({modules: {address} })export default store 創建modules文件夾&#xff1a;modul…

c# 簡單實現將Message的內容保存到txt中,超過100個則清理舊文件

using System; using System.IO; using System.Threading;public static class LogManager {private static readonly object _fileLock new object(); // 線程安全鎖private const int MaxFiles 100; // 最大文件數限制private const string LogDire…

阿里云鏡像加速僅支持阿里云產品了

最近在拉取docker鏡像時一直報超時的錯誤&#xff1a; docker pull hello-world Using default tag: latest Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exce…

從零實現Git安裝、使用

一、git安裝 Git官方下載 1.下載exe程序 2.雙擊安裝&#xff0c;一直點擊next&#xff0c;默認安裝 安裝完成后&#xff0c;在任意文件夾右鍵&#xff0c;出現下圖所示&#xff0c;即為安裝成功。 3.【Git Bash Here】調出命令窗口&#xff0c;設置用戶名和 email 地址。 gi…