C++ 线程 一些同步方式
- C++ 线程
- 一些同步方式
- 1.互斥锁(Mutex)
- 2. 读写锁(Reader-Writer Lock)
- 3. 信号量(Semaphore)
- 4. 原子操作(Atomic)
- 5. 屏障(Barrier)
- 6. 条件变量(Condition Variable)
一些同步方式
在多线程编程中,除了条件变量(condition variable)之外,还有其他几种常见的同步机制,每种机制都有其特定的使用场景和优势。以下是一些常见的同步方式:
1.互斥锁(Mutex)
互斥锁是最基本的同步机制,用于保护共享数据,防止多个线程同时访问导致数据竞争。
示例代码:
#include <iostream>
#include <thread>
#include <mutex>// 声明一个互斥锁对象
std::mutex mtx;// 声明一个共享数据变量,初始值为0
int shared_data = 0;// 线程函数:增加共享数据的值
void increment() {// 使用lock_guard锁定互斥锁,确保线程安全std::lock_guard<std::mutex> lock(mtx);// 增加共享数据的值shared_data++;
}int main() {// 创建两个线程,每个线程调用increment函数std::thread t1(increment);std::thread t2(increment);// 等待两个线程完成t1.join();t2.join();// 输出共享数据的最终值std::cout << "Shared data: " << shared_data << std::endl;// 返回0,表示程序正常结束return 0;
}
2. 读写锁(Reader-Writer Lock)
读写锁允许多个读线程同时访问共享数据,但写线程独占访问。适用于读多写少的场景。
示例代码:
#include <iostream>
#include <thread>
#include <shared_mutex>// 声明一个读写锁对象
std::shared_mutex rw_mtx;// 声明一个共享数据变量,初始值为0
int shared_data = 0;// 读线程函数:读取共享数据的值
void read() {// 使用shared_lock锁定读写锁,允许多个读线程同时访问std::shared_lock<std::shared_mutex> lock(rw_mtx);// 输出读取到的共享数据的值std::cout << "Read data: " << shared_data << std::endl;
}// 写线程函数:增加共享数据的值
void write() {// 使用unique_lock锁定读写锁,独占访问,阻止其他读写线程std::unique_lock<std::shared_mutex> lock(rw_mtx);// 增加共享数据的值shared_data++;// 输出写入后的共享数据的值std::cout << "Write data: " << shared_data << std::endl;
}int main() {// 创建一个读线程和一个写线程std::thread t1(read);std::thread t2(write);// 等待两个线程完成t1.join();t2.join();// 返回0,表示程序正常结束return 0;
}
3. 信号量(Semaphore)
信号量用于控制对共享资源的访问,可以用于线程间的同步和互斥。
示例代码:
#include <iostream>
#include <thread>
#include <semaphore>// 声明一个计数信号量对象,初始值为1
std::counting_semaphore<1> sem(1);// 声明一个共享数据变量,初始值为0
int shared_data = 0;// 线程函数:增加共享数据的值
void increment() {// 获取信号量,阻塞直到信号量可用sem.acquire();// 增加共享数据的值shared_data++;// 释放信号量,允许其他线程获取sem.release();
}int main() {// 创建两个线程,每个线程调用increment函数std::thread t1(increment);std::thread t2(increment);// 等待两个线程完成t1.join();t2.join();// 输出共享数据的最终值std::cout << "Shared data: " << shared_data << std::endl;// 返回0,表示程序正常结束return 0;
}
4. 原子操作(Atomic)
原子操作提供了一种无锁的同步机制,适用于对单个变量的简单操作。
示例代码:
#include <iostream>
#include <thread>
#include <atomic>// 声明一个原子整数变量,初始值为0
std::atomic<int> shared_data(0);// 线程函数:增加共享数据的值
void increment() {// 使用原子操作增加共享数据的值shared_data++;
}int main() {// 创建两个线程,每个线程调用increment函数std::thread t1(increment);std::thread t2(increment);// 等待两个线程完成t1.join();t2.join();// 输出共享数据的最终值std::cout << "Shared data: " << shared_data << std::endl;// 返回0,表示程序正常结束return 0;
}
5. 屏障(Barrier)
#include <iostream>
#include <thread>
#include <barrier>// 声明一个屏障对象,初始计数为3
std::barrier bar(3);// 工作线程函数:模拟工作并使用屏障进行同步
void worker() {// 输出工作线程开始的信息std::cout << "Worker started" << std::endl;// 到达屏障并等待,直到所有线程都到达屏障bar.arrive_and_wait();// 输出工作线程结束的信息std::cout << "Worker finished" << std::endl;
}int main() {// 创建三个线程,每个线程调用worker函数std::thread t1(worker);std::thread t2(worker);std::thread t3(worker);// 等待三个线程完成t1.join();t2.join();t3.join();// 返回0,表示程序正常结束return 0;
}
6. 条件变量(Condition Variable)
条件变量用于在一个线程等待某个条件成立时挂起该线程,并在条件成立时通知该线程继续执行。
示例代码:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>// 声明一个互斥锁对象
std::mutex mtx;// 声明一个条件变量对象
std::condition_variable cv;// 声明一个布尔变量,用于表示条件是否成立
bool ready = false;// 工作线程函数:等待条件成立并开始工作
void worker() {// 使用unique_lock锁定互斥锁std::unique_lock<std::mutex> lock(mtx);// 等待条件变量,直到ready为truecv.wait(lock, []{ return ready; });// 输出工作线程开始的信息std::cout << "Worker started" << std::endl;
}// 触发线程函数:设置条件并通知等待的线程
void trigger() {// 使用lock_guard锁定互斥锁std::lock_guard<std::mutex> lock(mtx);// 设置ready为true,表示条件成立ready = true;// 通知一个等待的线程cv.notify_one();
}int main() {// 创建一个工作线程和一个触发线程std::thread t1(worker);std::thread t2(trigger);// 等待两个线程完成t1.join();t2.join();// 返回0,表示程序正常结束return 0;
}相关文章:
C++ 线程 一些同步方式
C 线程一些同步方式 1.互斥锁(Mutex)2. 读写锁(Reader-Writer Lock)3. 信号量(Semaphore)4. 原子操作(Atomic)5. 屏障(Barrier)6. 条件变量(Condi…...
【开发语言】编译型语言和解释性语言有啥区别?
作为一名从业多年的程序员,对于编译型语言和解释型语言之间的区别有着深入的理解。这两种类型的编程语言在将源代码转换成可执行代码的过程中采用了不同的机制,这导致了它们在执行效率、跨平台性、安全性以及开发效率等方面存在一些差异。 编译型语言(Compiled Languages)…...
将A服务器上指定文件夹中的文件,批量同步到B服务器上
需求:最近有一个需求,需要定期将A服务器上的PDF文件,同步到B服务器上,于是便写个脚本记录一下! 下面是使用Python3脚本实现的方法 import os import paramikodef copy_pdf_files(source_ip, source_user, source_pas…...
2024.8.17
130124202408171002 DATE #:20240817 ITEM #:DOC WEEK #:SATURDAY DAIL #:捌月拾肆 TAGS < BGM "快哉风 -- 黄金玉米王" > < theme oi-language > < theme oi-graph theory > < [空] > < [空] >取次花丛懒回顾,半缘修道…...
十分钟搭建一个RTMP服务器
使用SRS搭建RTMP服务器 如果您需要搭建一个RTMP服务器,您可以使用SRS(Simple-RTMP-Server)来完成此任务。SRS是一个开源的RTMP服务器下面是一个简单的步骤指南: 获取srs srs官⽹:https://github.com/ossrs/srs 码云…...
Spring Boot解决循环注入问题
Spring Boot解决循环依赖注入问题 代码问题回显启动错误日志解决方案:使用事件驱动或通过 ApplicationContext 手动获取 Bean1. 事件驱动设计2. 使用 ApplicationContext 手动获取 Bean3. 拆分逻辑 总结 代码问题回显 现有代码1 在InterestService中依赖MemberInte…...
《数据挖掘》期末考核重点
1.数据预处理的目的与形式 数据预处理的目的是提供干净,简洁,准确的数据,以达到简化模型和提高算法泛化能力的目的,使挖掘过程更有效,更容易,提高挖掘效率和准确性。 2.数据预处理的形式 数据清理&#…...
Golang | Leetcode Golang题解之第334题递增的三元子序列
题目: 题解: func increasingTriplet(nums []int) bool {n : len(nums)if n < 3 {return false}first, second : nums[0], math.MaxInt32for i : 1; i < n; i {num : nums[i]if num > second {return true} else if num > first {second n…...
HarmonyOs编写一个案例实现一个照片选择(阶段进阶 四种需求 逐一完善)
需求1. .实现照片选择 并将选择好的照片展示出来 import { GoodItem } from ../06/modules;Entry Component struct PhotoPage {State message: string 实现一个相册;State List: GoodItem[] [{goods_name: dsfjlsjkfsf,goods_price: 100,goods_img: https://img1.baidu.com…...
洗衣机洗衣服一些知识
01智能:按衣物多少自动调节合适水位的标准洗涤程序 (需要30分钟时间) 02:大物:较大,较厚的衣服洗涤 03:轻柔:毛织品或内衣洗涤 04:快速:少量清污衣服洗涤 (13分钟) 05:浸泡:先浸泡一段时间再洗涤 06:单洗:只洗衣不脱水 07:单脱:只脱水不洗衣 08:洁桶:清洁洗衣桶 准备工作: (1)…...
探索文件系统:高效、可靠的文件管理与访问机制
文件系统的功能规划 内存就像是一个书包,容量有限,只能带着一部分东西。而图书馆则是一个专门存储和管理文件的地方,拥有更大的容量,并且可以永久保存文件。为了能够快速找到需要的文件,我们需要有一个书单来记录每本…...
启程与远征Ⅸ--优化生成式人工智能以满足业务需求的框架
生成类似人类的文本和语音曾经只存在于科幻小说中。但 GPT-3 和 PaLM 等大型语言模型 (LLM) 的快速发展让这一愿景更接近现实,解锁了从聊天机器人到内容创作等一系列有前景的商业应用。 然而,通用基础模型往往无法满足行业用例的需求。企业对其生成式 A…...
canal数据同步工具介绍与应用
canal服务 canal介绍canal版本与环境canal 服务集canal应用场景: canal常见问题xml配置问题连接认证问题jar版本问题连接问题 canal介绍 1、Canal是阿里巴巴开源的MySQL增量数据订阅和消费工具,通过模拟MySQL的slave与master交互,捕…...
ubuntu18.04 设置静态地址
修改配置文件 sudo vim /etc/netplan/01-network-manager-all.yaml 代码如下: network: version: 2 renderer: NetworkManager ethernets: ens33: # 配置的网卡名称,可以使用ifconfig -a查看本机的网卡 dhcp4: no # 关闭动态IP设置 …...
jira敏捷开发管理工具视频教程Confluence工作流协同开发(2024)
正文: 随着Jira敏捷开发方法论的普及,Jira已经成为全球软件开发团队管理项目、任务和问题的首选工具。为了帮助团队更好地掌握Jira的核心功能,精心准备了一套全面开发技术及案例视频教程——《Jira敏捷开发管理工具视频教程Confluenc…...
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
文章目录 ServerSocket构造方法方法 Socket构造方法方法 回显服务器(Echo Server)1. 构造方法2. 建立连接processConnection 方法的创建1. 读取请求并解析2. 根据请求计算响应3. 把响应写回给客户端 3. 完整代码 客户端(Echo Clientÿ…...
Python知识点:如何使用Boto3进行AWS服务管理
使用 boto3 来管理 AWS 服务是一个非常强大的方式,因为 boto3 是 AWS 提供的官方 Python SDK。下面是使用 boto3 管理 AWS 服务的基本步骤,包括设置、操作和常见的 AWS 服务示例。 1. 安装 boto3 首先,确保你已经安装了 boto3。可以使用 pi…...
Java - 正则表达式
Java 提供了 java.util.regex 包,它包含了 Pattern 和 Matcher 类,用于处理正则表达式的匹配操作。 正则表达式的模式 正则表达式的模式可以包括以下内容: 字面值字符:例如字母、数字、空格等,可以直接匹配它们自身。…...
Vue一款流行的JavaScript前端框架
1.Vue简介 Vue是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。 Vue所关注的核心是MVC…...
GPT-SoVITS
文章目录 model archS1 ModelS2 model model arch S1 model: AR model–ssl tokensS2 model: VITS,ssl 已经是mel 长度线性相关,MRTE(ssl_codes_embs, text, global_mel_emb)模块,将文本加强相关,学到一个参考结果 S1 Model cla…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
