本文首发于: 掘金
对于初次接触线程同步的前端来讲,老是对互斥锁、条件变量、信号量等术语傻傻分不清楚,这里根据本身的理解简单作下总结,若有疏漏之处,欢迎你们批评指正。前端
在多线程环境中每每存在因某一资源被同时访问致使该资源不一致的问题,互斥锁
经过排它性,即同时只容许一个访问者对其进行访问来保证资源的有效同步,但它没法限制线程对该资源的访问顺序,所以线程对资源的访问也是无序的。多线程
在互斥锁
中,若是线程 A 在请求锁的时候发现该锁已被线程 B 霸占,那么此时线程 A 便会进入休眠状态,直到锁被线程 B 释放后被系统唤醒。但在自旋锁
中,线程 A 在发现锁被霸占时并不进入休眠,而是一直循环查看锁的持有者是否已经释放了该锁。初看起来,这种霸占CPU资源的作法极其低效,但与互斥锁
仔细对比后咱们能够发现它有如下几个优势:post
互斥锁
休眠、唤醒所涉及的一系列上下文切换、CPU抢占等各类复杂流程。固然,上面的高效也是有条件的,因为它占用CPU资源,因此它主要适用于如下场景:学习
递归锁
又叫可重入锁
,与 互斥锁
的主要区别是在同一个线程内能够屡次得到锁资源,别的线程必须等待该线程释放相应次数的锁才能得到,其主要目的是为了解决同一进程内的死锁问题,但在不一样的线程中,它与互斥锁
并无什么区别。线程
上面介绍的互斥锁
、自旋锁
、递归锁
都属于排它锁,即一个线程得到锁资源后,其余线程必须等待直到该锁被释放。但在某些读多写少的状况下,这样的机制不免有些低效,所以读写锁
就是为解决这样的问题而诞生的。读写锁分读锁和写锁,其特色以下:3d
条件变量
主要适用于一个线程须要等待某个共享资源知足某个条件后进行一系列同步操做的场景。它主要包含:code
它通常与互斥锁
配合使用(主要用来保护共享资源),在等待线程中,若是条件不成立,该线程会自动阻塞,并释放掉等待状态改变的互斥锁,若是信号发送线程改变了条件,它发送信号给关联的条件变量,并唤醒等待线程,等待线程从新得到互斥锁,从新评估条件。递归
信号量
主要适用于一个线程须要等待另一个个线程完成一些操做后再继续执行本身操做的场景,它与上面各类锁的最大区别是:进程
信号量
要解决的是线程之间任务同步问题。信号量
能够经过一个线程中获得,在另外一个线程中释放。认真回味下咱们会发现信号量
要解决的问题也可使用条件变量
来处理,相对于信号量
,条件变量
主要有如下不足:资源
条件变量
须要借助全局共享变量以及互斥锁
来达到状态的检测。条件变量
适用于多线程环境,没法适用于多进程环境。屏障
是一种协调多个线程进行工做,即容许某个线程等待直到全部的合做线程达到某一个条件,而后从该条件下继续执行的同步机制。
本文对线程同步中所涉及到的术语的特色及适用场景进行了简单的总结,若是你在阅读过程当中发现任何错误,欢迎留言指正,咱们一块儿学习一块儿进步。^ _ ^