线程同步相关术语总结

本文首发于: 掘金

对于初次接触线程同步的前端来讲,老是对互斥锁、条件变量、信号量等术语傻傻分不清楚,这里根据本身的理解简单作下总结,若有疏漏之处,欢迎你们批评指正。前端

互斥锁

在多线程环境中每每存在因某一资源被同时访问致使该资源不一致的问题,互斥锁 经过排它性,即同时只容许一个访问者对其进行访问来保证资源的有效同步,但它没法限制线程对该资源的访问顺序,所以线程对资源的访问也是无序的。多线程

自旋锁

互斥锁中,若是线程 A 在请求锁的时候发现该锁已被线程 B 霸占,那么此时线程 A 便会进入休眠状态,直到锁被线程 B 释放后被系统唤醒。但在自旋锁中,线程 A 在发现锁被霸占时并不进入休眠,而是一直循环查看锁的持有者是否已经释放了该锁。初看起来,这种霸占CPU资源的作法极其低效,但与互斥锁仔细对比后咱们能够发现它有如下几个优势:post

  • 实现简单:只需死循环检测锁状态便可,没有互斥锁休眠、唤醒所涉及的一系列上下文切换、CPU抢占等各类复杂流程。
  • 高效:正是因为实现极其简单,因此它在一些状况下极其高效。

固然,上面的高效也是有条件的,因为它占用CPU资源,因此它主要适用于如下场景:学习

  • 临界区持锁时间较短且CPU资源不紧张。
  • 多用于多核环境。

递归锁

递归锁又叫可重入锁,与 互斥锁的主要区别是在同一个线程内能够屡次得到锁资源,别的线程必须等待该线程释放相应次数的锁才能得到,其主要目的是为了解决同一进程内的死锁问题,但在不一样的线程中,它与互斥锁并无什么区别。线程

读写锁

上面介绍的互斥锁自旋锁递归锁都属于排它锁,即一个线程得到锁资源后,其余线程必须等待直到该锁被释放。但在某些读多写少的状况下,这样的机制不免有些低效,所以读写锁就是为解决这样的问题而诞生的。读写锁分读锁和写锁,其特色以下:3d

  • 读锁:若是线程 A 得到了读锁,线程 B 能够得到读锁,但不能够得到写锁。
  • 写锁:若是线程 A 得到了写锁,线程 B 即不能够得到读锁,也不能够得到写锁。
  • 写锁优先:若是线程 A 申请得到写锁,线程 B 申请得到读锁,优先给线程 A 分配写锁。

条件变量

条件变量主要适用于一个线程须要等待某个共享资源知足某个条件后进行一系列同步操做的场景。它主要包含:code

  • 等待某个条件成立的等待线程。
  • 知足某个条件成立的信号发送线程。

它通常与互斥锁配合使用(主要用来保护共享资源),在等待线程中,若是条件不成立,该线程会自动阻塞,并释放掉等待状态改变的互斥锁,若是信号发送线程改变了条件,它发送信号给关联的条件变量,并唤醒等待线程,等待线程从新得到互斥锁,从新评估条件。递归

信号量

信号量主要适用于一个线程须要等待另一个个线程完成一些操做后再继续执行本身操做的场景,它与上面各类锁的最大区别是:进程

  • 锁要解决的是共享资源的同步问题,而信号量要解决的是线程之间任务同步问题。
  • 锁必须在同一进程进行加锁和解锁操做,而信号量能够经过一个线程中获得,在另外一个线程中释放。

认真回味下咱们会发现信号量要解决的问题也可使用条件变量来处理,相对于信号量条件变量主要有如下不足:资源

  • 条件变量须要借助全局共享变量以及互斥锁来达到状态的检测。
  • 条件变量适用于多线程环境,没法适用于多进程环境。

屏障

屏障是一种协调多个线程进行工做,即容许某个线程等待直到全部的合做线程达到某一个条件,而后从该条件下继续执行的同步机制。

总结

本文对线程同步中所涉及到的术语的特色及适用场景进行了简单的总结,若是你在阅读过程当中发现任何错误,欢迎留言指正,咱们一块儿学习一块儿进步。^ _ ^

相关文章
相关标签/搜索