内核专家 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
分享到:
相关推荐
直接就放在书上,你丫有没有良知,书籍是什么,是希望,是神圣的,你们这些译者简直就是在犯罪 ,不过要是英文功底不好,还是建议买本看吧,谁让你英文水平不如他们呢 《JAVA并发编程实践》随着多核处理器的普及,...
Java并发编程的艺术 作者:方腾飞 魏鹏 程晓明 著 丛书名:Java核心技术系列 出版日期 :2015-07-25 ISBN:978-7-111-50824-3 第1章介绍Java并发编程的挑战,向读者说明进入并发编程的世界可能会遇到哪些问题,以及如何...
建议学习实践: ...1. 要坚持实践高性能大并发编程的实践 2. Erlang基础->OTP高并发编程实践PDF->Elixir 3. 认真实践本书中的知识点, 动手练习, 高并发软件实时大容量的服务器开发可打败C++的大团队开发
如果你是一名并发编程初学者,建议按照顺序阅读本书,并按照书中的例子进行编码和实战。如果你有一定的并发编程经验,可以把本书当做一个手册,直接看需要学习的章节。以下是各章节的基本介绍。第1章介绍Java并发...
并发编程面试专题,成为一名java程序员必备书籍,建议java工程师认真阅读。
java并发编程实践源码,官方下的源码,建议大家用的时候重写,不会再看源码
第1章介绍Java并发编程的挑战,会向读者说明可能会遇到哪些问题,以及如何解决。第2章Java并发编程的底层实现原理,从CPU和JVM2个层面剖析。第3章详细深入介绍了Java的内存模型。第4章从介绍多线程技术带来的好处...
Java并发编程实践中的话:编写正确的程序并不容易,而编写...本场Chat作为Java并发编程之美系列的高级篇之二,主要讲解内容如下:(建议先阅读:Java编程之美:并发编程高级篇之一)rt.jar中Unsafe类主要函数讲解,Un
接着讲解了并发编程中的原子操作与互斥锁来实现线程安全。最后从局部性原理和内存对齐等方面介绍了性能优化思想,并给出了使用原子操作与互斥锁进行内存管理的完整示例代码。内容全面系统地概述了C++内存管理的知识。...
2万字Java并发编程面试题合集(含答案,建议收藏) 具体如下 1、在 java 中守护线程和本地线程区别?2、线程与进程的区别?3、什么是多线程中的上下文切换?4、死锁与活锁的区别,死锁与饥饿的区别?5、Java 中用到...
讲述java并发的好文章,从底层描述并发的实际机制,讲的比较深刻,高级咖啡啊建议一读
博客有完整源码,积分不够的小伙伴直接去博客复制不用下载,不会使用的也可以参考下博客,只是简单编写了握手过程用于了解协议,实际开发建议使用成熟框架
Golang技术文档,清晰PDF扫描,有目录,建议对go有兴趣的爱好者一起提升!其中对go的并发原理部分讲的不错,可以着重看一下! 本书在图灵社区的主页: http://www.ituring.com.cn/book/1950 在Github上的主页: ...
《安琪拉教百里守约学并发编程》系列文章 安琪拉教百里守约学并发编程之多线程基础 本文是来自读者群里@凯的建议,决定开一个多线程的专栏,尊重读者安琪拉是认真的,为什么是教百里守约,也是因为读者群里@百里守约...
ID1019-编程II 这是KTH皇家技术学院提供的函数式和并发编程课程。 最初使用的编程语言是Erlang,但现在我们转向Elixir。讲课将有14堂讲座将讲解功能和并发编程的概念。 我们将使用Elixir作为示例语言,但讲座更侧重...
介绍java多线程的超经典的书,不需要多介绍了。这是完整版。压缩包内包含两个版本的pdf,都是英文版。建议看英文版,因此中文版翻译得超烂。与此同时,压缩包内还有一个java多线程总结.ppt!
项目-实时策略游戏并发编程 项目范围: 实施实时多人网络策略游戏。 中世纪文明的风格; 第1部分的范围: 实施部分游戏:村庄; 仅考虑一名玩家; 在开始游戏之前,玩家必须告知他的名字并选择他的文明...