并发编程的 15 条建议

内核专家 Bryan Cantrill 和 Jeff Bonwick 在 2008 年 9 月的《ACM Queue》上发表了《Real-world Concurrency》 一文,提出了 15 条并发编程的建议,这里简单摘录如下。注:Bryan Cantrill 是 dtrace 的主要作者,Jeff Bonwick 是 ZFS 和 Slab allocator 的发明者。

1. Know your cold paths from your hot paths. 弄清楚代码里的热门执行路径和冷门执行路径。

对冷门路径,用粗粒度的锁即可。对热门路径——也就是那些必须高度并发才能实现所期望的高吞吐量的代码,应该更加小心,加锁的策略必须简单明了且细粒度。

2. Intuition is frequently wrong—be data intensive. 直觉常常是错的,要靠数据说话。

【陈硕】比如线程切换到底有多大开销,普通 mutex 加锁到底有多大代价,系统调用的开销如何,gettimeofday() 在 x86-64 Linux 是不是真的系统调用等等,都要靠数据说话。

3. Know when—and when not—to break up a lock. 知道什么时候把一个锁拆成多个,并知道什么时候不必这样做。

除了把全局锁拆成多个锁,另外一种常用的避免线程争用 (contention) 的办法是减少加锁的范围。比方说从共享的数据结构里移除(remove and delete)元素,其实 delete 这一步可以放到锁外面。

4. Be wary of readers/writer locks. 警惕读写锁。

初学者常犯的一个错误是,见到某个数据结构频繁读而很少写,那么就把 mutex 替换为 rwlock。这不见得是正确的。

【陈硕】这条深得我心,muduo thread lib 目前就没有提供读写锁的封装。另外,这一条也能鉴别另一篇关于线程争用的文章 不靠谱。

5. Consider per-CPU locking. 考虑用每个 CPU 用一个锁。

6. Know when to broadcast—and when to signal. 知道什么时候用单个唤醒,什么时候用广播唤醒。

notifyAll() 通常表示状态变更,而 notify() 通常表示资源变得可用。滥用 notifyAll() 会导致惊群现象 。

【陈硕】 muduo thread lib 的 ThreadPool 区分使用 notify() 和 notifyAll(),可作参考。

7. Learn to debug postmortem. 学会验尸。

【陈硕】 在程序中只使用 Scoped locking 来加锁的话,很容易从 call stack 查出死锁。参考《多线程服务器的常用编程模型》 第 6 节 线程间同步。

8. Design your systems to be composable. 设计系统,使之能扩充。

【陈硕】 比方说,把对对象的修改操作都挪到同一个线程,这样就不必加锁。参考 muduo 的 EventLoop::runInLoop()。

9. Don’t use a semaphore where a mutex would suffice. 如果 Mutex 就能解决问题的话,不要使用信号量 semaphore。

【陈硕】muduo thread lib 有意识地不提供信号量的封装。

10. Consider memory retiring to implement per-chain hash-table locks. 考虑用内存“退休”法来实现哈希表的按桶加锁。

11. Be aware of false sharing. 知道什么是伪共享。

跟多 CPU 的 Cache 有关,值得了解。

12. Consider using nonblocking synchronization routines to monitor contention. 考虑使用非阻塞的加锁来观察线程争用。

13. When reacquiring locks, consider using generation counts to detect state change. 在重新加锁时,考虑使用版本号来检测状态变更。

14. Use wait- and lock-free structures only if you absolutely must. 只在别无它法时才使用无锁数据结构。

15. Prepare for the thrill of victory—and the agony of defeat. 准备接受成功的喜悦和失败的痛苦。

中文转自: 陈硕的 Blog

1. 基于STM32的1.28寸圆形IPS屏(GC9A01)驱动移植实战:软件SPI与硬件SPI双方案详解 本文详细介绍了如何在STM32平台上为1.28寸圆形IPS屏(GC9A01驱动芯片)移植驱动程序,涵盖软件SPI与硬件SPI两种实现方案。内容从引脚定义、工程搭建、GPIO配置到SPI外设初始化逐步详解,并提供了完整的测试代码,帮助开发者根据项目需求(灵活性或性能)选择合适的通信方式,快速点亮屏幕并集成到智能手表等嵌入式项目中。 阅读详情

相关推荐

【Collibra 驱动 IPD 数据血缘治理】:三层图谱分层展示体系与全链路追踪的技术业务实践

(应用级/数据级/字段级)是理解复杂数据流动的核心手段。其价值不仅体现在可视化的直观性,更在于通过。技术保障血缘不可篡改性,进一步提升IPD数据治理的可靠性。,解决了跨层级血缘分析的性能与可用性矛盾。数据血缘图谱要素定义(字节跳动/腾讯云/信安标委)实现对IPD数据的精准追踪,而数据血缘图谱的。分层交互设计标准(智慧城市数据中台规范)Collibra技术文档(2024)字段级血缘的挑战与解决路径。自动优化血缘路径,并深化。字段级血缘技术实现方案。Collibra通过。图数据库性能优化原理。

百态·数智思维 | 聚焦大数据、量化与未来AI 1244

并发编程的15 条建议

内核专家 Bryan Cantrill 和 Jeff Bonwick 在 2008 年 9 月的《ACM Queue》上发表了《Real-world Concurrency》 一文,提出了 15 条并发编程的建议,这里简单摘录如下。1. Know your cold paths from your hot paths. 弄清楚代码里的热门执行路径和冷门执行路径。对冷门路径,用粗粒度的锁即可。对热门路径——也就是那些必须高度并发才能实现所期望的高吞吐量的代码,应该更加小心,加锁的策略必须简单明了且细粒度。2.

I will work my left life for my family 1616

瑞萨单片机,把CS文件转换为CC

1、打开CC的软件: 点击坐上角的"START" 点击"Create New Project"的"GO": 导入工程: 如下图设置后,点击"Create" 2、进入到CC的开发界面: 可以看到原启动库文件以asm文件的方式直接出现在工程中: 删除新生成的main.c,保留导入的r_main.c(以你自己的代码为准): 注意添加所有的头文件路径: 点击"...

weixin_37611121的博客 1228

并发编程的 15 条建议(译)

内核专家 Bryan Cantrill 和 Jeff Bonwick 在 2008 年 9 月的《ACM Queue》上发表了《Real-world Concurrency》 一文,提出了 15 条并发编程的建议,这里简单摘录如下。 1. Know your cold paths from your hot paths. 弄清楚代码里的热门执行路径和冷门执行路径。 对冷门路径,用粗粒度的锁即可。对热门路径——也就是那些必须高度并发才能实现所期望的高吞吐量的代码,应该更加小心,加锁的策略必须简单明了且细粒

陈硕的Blog 3万+

学习 Bootstrap 5 之 Tables

学习 Bootstrap 5 之 表格表格 (Tables)1. 创建表格(1). 使用原生的表格标签(2). 使用Bootstrap 5 的提供的表格标签类(3). 原生与Bootstrap创建出来的表格的对比2. 表格样式(1). 表格样式的效果(2). 表格样式的使用1). 用于 <table> 标签2). 用于 <thead> <tbody> <tfoot> 标签 表格 (Tables) 1. 创建表格 (1). 使用原生的表格标签 <tabl

qq_37354060的博客 2130

实战教程:如何用Python+小波变换+CNN搞定医学影像中的条纹噪声(附完整代码)

本文提供了一套完整的实战方案,指导如何利用Python结合小波变换与卷积神经网络(CNN)去除医学影像中的条纹噪声。该方法通过小波变换精准定位噪声,再使用轻量化CNN进行针对性清除,有效保护图像细节,并附有可运行的完整代码,为医学影像处理与AI分析提供高效工具。

weixin_29056101的博客 269

并发编程的 15 条建议(译) zz

<br /><br />内核专家 Bryan Cantrill 和 Jeff Bonwick 在 2008 年 9 月的《ACM Queue》上发表了《Real-world Concurrency》 一文,提出了 15 条并发编程的建议,这里简单摘录如下。<br />1. Know your cold paths from your hot paths. 弄清楚代码里的热门执行路径和冷门执行路径。<br />对冷门路径,用粗粒度的锁即可。对热门路径——也就是那些必须高度并发才能实现所期望的高吞吐量的代码,应

Neil 368

基于紫光展锐平台的音频调用到hal层逻辑

基于紫光展锐平台的音频调用到hal层逻辑 1、数据流程图 AudioPolicyService和AudioFlinger的创建: 这两个服务都在audioserver中启动,文件路径: frameworks/av/media/audioserver/main_audioserver.cpp 从AudioFlinger和AudioPolicyService的创建,到output的打开,以及AudioFlinger开始往底层写入数据的具体流程如下图: #mermaid-svg-kjHL4XWwkQXN6NdA

weixin_55053963的博客 1355

第15章 并发编程

Rust并发编程摘要 Rust通过所有权系统和类型系统提供了安全高效的并发编程能力。本章介绍了线程管理、消息传递和共享状态三种并发模型。 线程管理 使用thread::spawn创建线程,join等待完成 线程闭包常用move获取数据所有权 可配置线程名称、栈大小等属性 线程恐慌不会自动传播,需通过JoinHandle检测 消息传递 使用mpsc::channel创建通道 支持多生产者单消费者模式 通道在发送端被丢弃时自动关闭 同步通道可在发送时阻塞直到消息被接收 共享状态 Arc实现线程安全引用计数 Mu

百锦再的博客 1万+

Shopee商品详情页反爬实战:手把手逆向x-sap-Ri和x-sap-Sec请求头加密

本文详细解析了Shopee商品详情页反爬机制中x-sap-Ri和x-sap-Sec请求头参数的加密逻辑,通过JS逆向技术手把手教你定位加密入口、分析哈希算法与对称加密实现,并提供完整实战案例和应对反爬策略的高级技巧,助力开发者突破电商平台数据采集难点。

weixin_27875131的博客 1826

【实战指南】从零构建UNet多分类分割数据集:标注、转换与训练全流程

本文提供了一份从零构建UNet多分类分割数据集的完整实战指南。详细介绍了使用Labelme进行图像标注的核心技巧与规范,并通过Python脚本将标注结果转换为模型可用的VOC格式。最后,指导如何修改经典的PyTorch版UNet代码,以适配自定义数据集并进行训练与测试,帮助读者完成从数据准备到模型训练的全流程。

arduino9maker的博客 288

Java并发编程实战 Day 15:并发编程调试与问题排查

在高并发系统中,线程之间的交互复杂、状态难以预测,导致调试和问题排查成为开发者的“噩梦”。本文作为“Java并发编程实战”系列的第15天,深入讲解了并发编程中的常见问题及其调试方法。文章从理论出发,解析了死锁、活锁、资源竞争等核心问题的本质,并结合JVM层面的实现机制进行分析。通过实际代码示例和性能测试,展示了如何使用工具如jstack、jconsole、VisualVM等进行问题定位与优化。同时,结合真实工作场景中的案例,详细说明了问题的发现、分析与解决过程。

在未来等你的专栏 972

uniapp - 应用软件在运行时,未见向用户告知权限申请的目的,向用户索取(存储、相机、电话)等权限,不符合华为应用市场审核标准(uniApp开发安卓APP上架应用市场审核被拒绝驳回,详细解决方案)

uniApp应用软件在运行时,未见向用户告知权限申请的目的,向用户索取(存储、相机、电话)等权限,不符合华为应用市场审核标准。uniapp vue2 vue3解决软件在运行时,未见向用户告知权限申请的目的,华为等上架被拒问题,关于华为应用市场上架需要同步告知使用权限的解决方案,uniApp应用软件在运行时,不符合华为应用市场审核标准。解决方案合集!app上架-您的应用在运行时,未同步告知权限申请的使用目的,向用户索取(相机)等权限,不符合华为应用市场审核标准。华为应用市场审核新规(未同步告知权限申请的使用目

🏆 前端领域优质创作者 4164

树相关算法工具、redis相关操作15条建议、SCF API 实现

一、tag 树 import com.google.common.collect.Maps; import com.google.common.collect.Lists; import lombok.Data; import org.springframework.util.CollectionUtils; import java.util.List; import java.util.Map; /** * tag 树 */ public class TagTools { /**

点点的博客 243

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

2万字Java并发编程面试题合集(含答案,建议收藏)

Java 并发编程 1、在 java 中守护线程和本地线程区别? 2、线程与进程的区别? 3、什么是多线程中的上下文切换? 4、死锁与活锁的区别,死锁与饥饿的区别? 5、Java 中用到的线程调度算法是什么? 6、什么是线程组,为什么在 Java 中不推荐使用? 7、为什么使用 Executor 框架? 8、在 Java 中 Executor 和 Executors 的区别? 9...

程序员追风的博客 2万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

《Effective Python》读书笔记14: 附录 - 90条建议完整列表

作者: andylin02学习章节: 全书90条建议速查表关键词: Effective Python, 90条建议, Python进阶, 最佳实践。

1673

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Java并发编程学习 + 原理分析(建议收藏)

个人博客欢迎访问 作者总结不易,点赞,关注支持一下。 Doug Lea是一个无私的人,他深知分享知识和分享苹果是不一样的,苹果会越分越少,而自己的知识并不会因为给了别人就减少了,知识的分享更能激荡出不一样的火花。 目录线程介绍程序、进程、线程基本概念进程与线程的区别什么是上下文切换串行、并行和并发有什么区别使用多线程的优缺点何时需要多线程并发编程的三要素线程实现线程的创建和使用线程的创建和启动扩展问题run()和start()有什么区别为什么我们调用 start() 方法时会执行 run() 方法,

qq_45796208的博客 2096

15个多线程相关的面试题【建议收藏】

15个多线程相关的面试题【建议收藏】

小二丶的博客 2928

15年java编程经验大佬建议这样学java,元芳你怎么看?

就在昨天,我在论坛问答中发表这个话题,其中有位15年java编程经验的大佬是这样回答的,说是回答我看更像是文章,可见这位大佬也是很用心的了,作为后辈小生颇感荣幸,于是意味深长的读了许久,思考良久,受益匪浅。文章具体是这样写的: 如果上天再给我一次机会,我会这样学Java 回头看看, 我进入Java 领域已经快15个年头了, 虽然学的也一般, 但是分享下我的心得,估计也能帮大家少走点弯路。 [入门]...

宜春 2383
上一篇: 云计算入门:云计算不等于分布式计算
下一篇: 云计算的可伸缩性局限性探讨
lylhelin
博客等级 码龄21年 9粉丝 215原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值