论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com技术社区
»
论坛
›
大数据
›
数据仓库与分析
›
多线程编程:线程间的同步与通讯
多线程编程:线程间的同步与通讯
伤心客
论坛元老
|
2024-12-5 15:49:59
|
显示全部楼层
|
阅读模式
楼主
主题
1706
|
帖子
1706
|
积分
5118
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
多线程编程:线程间的同步与通讯
一、概述
在多线程编程中,必须解决以下两个核心问题:
线程间的互斥
:确保共享资源在同一时刻只被一个线程访问,防止数据竞争。
线程间的同步通讯
:使线程之间按照指定序次执行,以实现任务协调和依赖关系。
二、线程间的互斥
1. 静态条件与临界区
静态条件
:多线程步伐在差异执行序次下可能产生不一致的结果。
临界区
:代码中访问共享资源的部分。
解决方法:每次只能允许一个线程进入临界区。
2. 互斥锁(Mutex)
作用
:
包管临界区代码段的原子性。
防止多个线程同时访问共享资源。
实现方式
:
使用 std::mutex 加锁和解锁。
对于较小的临界区,可以使用轻量级的无锁机制(如 CAS)。
三、线程间的同步通讯
1. 同步通讯的必要性
多线程步伐中,线程的执行序次由操纵系统调理决定,通常是不确定的。
在某些场景下,线程必要依赖其他线程的执行结果。例如:
生产者-消费者问题
:生产者必要将数据生产完毕后关照消费者举行消费。
2. 条件变量(Condition Variable)
作用
:实现线程间的同步通讯。
特点
:
必要与 std::mutex 搭配使用。
提供 wait 和 notify 方法,实现线程间的协调。
四、生产者-消费者模子
1. 问题描述
生产者线程负责生产数据,并将数据放入队列;消费者线程负责从队列中取出数据并消费。
目标
:
包管生产者和消费者交替工作。
防止队列为空时消费者消费数据或队列溢出时生产者继续生产。
2. 代码实现
全局变量
std::queue<int> q; // 共享队列
std::mutex mtx; // 互斥锁
std::condition_variable cv; // 条件变量
复制代码
生产者函数
void producer() {
for (int i = 1; i <= 10; ++i) {
std::unique_lock<std::mutex> lock(mtx); // 加锁
q.push(i); // 生产数据
std::cout << "Produced: " << i << std::endl;
cv.notify_all(); // 通知消费者
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产时间
}
}
复制代码
消费者函数
void consumer() {
for (int i = 1; i <= 10; ++i) {
std::unique_lock<std::mutex> lock(mtx); // 加锁
cv.wait(lock, [] { return !q.empty(); }); // 等待队列非空
int value = q.front(); // 获取数据
q.pop(); // 移除数据
std::cout << "Consumed: " << value << std::endl; // 打印消费日志
lock.unlock(); // 解锁
cv.notify_all(); // 通知生产者
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟消费时间
}
}
复制代码
主函数
int main() {
std::thread t1(producer); // 创建生产者线程
std::thread t2(consumer); // 创建消费者线程
t1.join(); // 等待生产者线程完成
t2.join(); // 等待消费者线程完成
return 0;
}
复制代码
3. 核心逻辑
同步通讯的实现
生产者和消费者的协调
:
生产者生产数据后通过 cv.notify_all() 关照消费者。
消费者消费数据后通过 cv.notify_all() 关照生产者。
防止竞争和死锁
:
使用 std::mutex 确保队列的操纵线程安全。
cv.wait 确保消费者只有在队列非空时才执行操纵。
4. 状态厘革分析
变乱状态举动消费者发现队列为空阻塞等候生产者生产数据后被关照生产者生产数据队列非空,关照消费者消费者从等候状态转为阻塞状态,等候获取锁继续执行消费者消费数据队列可能为空,关照生产者生产者从等候状态转为阻塞状态,等候获取锁继续执行
6. 注意事项
线程安全
:
队列的全部操纵(如 push 和 pop)必须在加锁状态下举行。
条件变量使用
:
wait 必须传入一个 std::unique_lock<std::mutex> 对象。
notify_all 应用于多个消费者时,notify_one 适用于单一消费者场景。
死锁防范
:
确保每个线程在进入 wait 状态前释放锁。
五、总结
互斥锁的作用
:
确保线程安全,制止共享资源的并发访问导致的数据竞争。
条件变量的作用
:
线程间的同步通讯,协调线程的执行序次。
核心操纵
:
std::mutex:加锁与解锁。
std::condition_variable:线程等候(wait)与关照(notify_all 和 notify_one)。
生产者-消费者模子的实现
:
使用共享队列举行数据通报。
条件变量协调线程之间的依赖序次。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
伤心客
论坛元老
这个人很懒什么都没写!
楼主热帖
《百万IT毕业生的心声:IT专业大学生毕 ...
Java打怪之路----谷粒商场认证服务 ...
xtrabackup2版本和xtrabackup8版本对比 ...
Excelize 发布 2.6.1 版本,支持工作簿 ...
sqlserver导入sql文件的方式
原型设计工具比较及实践--滴爱音乐 ...
Snowflake(雪花算法),什么情况下会 ...
Flink-使用流批一体API统计单词数量 ...
SQL Server 2008下载及安装
基于 SpringBoot + MyBatis 的博客系统 ...
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
物联网
快速回复
返回顶部
返回列表