第2章线程同步精要

并发编程有两种模型,一种是message passing,另一种是 shared memory。在分布式系统中,运行在多台机器上的多个进程的并行编程方式只有 message passing。

线程同步的4项原则,按重要性排序:

  • 首先原则是尽量最低限度的共享对象,减少需要同步的场合。一个对象能不暴露给别的线程就不要暴露;如果要暴露,优先考虑immutable 对象;实在不行才暴露可修改的对象,并用同步措施来充分保护它。
  • 其次是使用高级的并发编程构件,如TaskQueue、Producer-Consumer Queue、CountDownLatch等等。
  • 最后不得已必须使用同步底层原语时,只用非递归的互斥器和条件变量,慎用读写锁,不要用信号量。
  • 除了使用atomic整数外,不自己编写lock-free代码,也不要用“内核级”同步原语。不凭空猜测“哪种做法会更好”。
互斥器(mutex)

互斥器(mutex)恐怕是使用得最多的同步原语,粗略地说,它保护了临界区,任何一个时刻最多只能有一个线程在此mutex划出的临界区内活动。单独使用mutex时,我们主要为了保护共享数据。作者的原则是:

  • 用RAII手法封装mutex创建、销毁、加锁、解锁这四个操作。用RAII封装这几个操作是通行的做法,这几乎是C++的标准实践,保证锁的生效期间等于一个作用域,不会因异常而忘记解锁。
  • 只用非递归的mutex,即不可重入的mutex。
  • 不手工调用lock()和unlock()函数,一切交给栈上的Guard对象的析构和析构函数负责。
  • 在每次构造Guard对象的时候,思考一路上已经持有的锁,防止因加锁顺序不同而导致死锁。

次要原则有:

  • 不使用跨进程的mutex,进程间通信只用TCP sockets。
  • 加锁、解锁在同一个线程。
  • 别忘了解锁(RAII自动保证)
  • 不要重复解锁(RAII自动保证)
  • 必要的时候可以考虑使用PTHREAD_MUTEX_ERRORCHECK 来排错。
只使用非递归的mutex

mutex 分为递归和非递归两种,这是POSIX的叫法,另外的名字叫做可重入和非可重入。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 引用自多线程编程指南应用程序里面多个线程的存在引发了多个执行线程安全访问资源的潜在问题。两个线程同时修改同一资源有...
    Mitchell阅读 2,137评论 1 7
  • 对于从多个执行线程安全访问资源,应用程序中多个线程的存在会导致潜在的问题。修改相同资源的两个线程可能会以出乎意料的...
    渐z阅读 450评论 0 0
  • 我曾经在不知名的深夜想过无数次 是否这世界上的人都是因为想要生而生 是否这世界上的人都是日复一日的重复着自己或是重...
    Dinya阅读 230评论 0 0
  • 天空突然把自己倒空大地接纳了几条河流世界就湿润了起来 榕树接纳了几只小鸟榕树就鲜活了起来 天的那边什么都没有我跟着...
    半月婵阅读 1,040评论 25 33
  • 口语学习需要不断的去训练自己,把一件小事做好,真的很不容易! 把之前的文本都背一遍,这些都是经过你认真背诵的基础上...
    千寻的玉簪阅读 83评论 0 0

友情链接更多精彩内容