参考:自旋锁和互斥锁的区别_Yisnow.的博客-CSDN博客_自旋锁和互斥锁的区别
结论:1. 当出现加锁失败的情况———互斥锁使用线程切换应对;自旋锁使用忙等待应对;更高级的锁都会选择其中一个实现。
2. 若是能确定被锁住的代码执行时间很短,就不应该使用互斥锁,而应该选择自旋锁。
互斥锁
特点:
1、当线程加锁失败时,内核将线程的状态从【运行】切换到睡眠状态,然后把CPU切换给其他线程运行;
2、当锁被释放时,之前睡眠状态的线程会变成就绪状态,然后内核就会在合适的时间把CPU切换给该线程运行;
性能开销成本——两次线程上下文切换的成本。
【当两个线程属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。
上下切换的耗时大概在几十纳秒到几微秒之间,如果锁住的代码执行时间比较短,可能上下文切换的时间比锁住的代码执行时间还要长】
自旋锁
通过CPU提供的CAS,在用户态完成加锁和解锁操作,不会主动产生线程上下文切换,所以相比互斥锁来说,会快并且开销小一些。
加锁过程:查看锁的状态,若是空闲的则执行2;将锁设置为当前线程持有;
特点:
1. 使用自旋锁的时候,当发生多线程竞争锁的情况,加锁失败的线程会忙等待,直到拿到锁。忙等待可以通过while循环实现,不过最好是使用CPU提供的PAUSE指令来实现。
2. 自旋锁利用CPU周期一直自旋直到锁可用。由于一个自选的线程永远不会放弃CPU,因此在单核CPU上,需要抢占式的调度器(不断通过时钟中断一个线程,运行其他线程)。
自旋的时间和被锁住的代码执行的时间成正比关系。