自旋锁跟互斥锁对比

自旋锁和互斥锁是多线程编程中的两种同步机制。互斥锁在加锁失败时会将线程切换到睡眠状态,而自旋锁则会让线程忙等待,直到获取锁。互斥锁涉及两次线程上下文切换,适合保护长时间运行的代码。自旋锁开销较小,适用于短时加锁场景,但不适合单核环境。选择哪种锁取决于代码执行时间和系统资源。

参考:自旋锁和互斥锁的区别_Yisnow.的博客-优快云博客_自旋锁和互斥锁的区别

结论

        1. 当出现加锁失败的情况———互斥锁使用线程切换应对;自旋锁使用忙等待应对;更高级的锁都会选择其中一个实现。

        2. 若是能确定被锁住的代码执行时间很短,就不应该使用互斥锁,而应该选择自旋锁。

互斥锁

在这里插入图片描述

特点:
        1、当线程加锁失败时,内核将线程的状态从【运行】切换到睡眠状态,然后把CPU切换给其他线程运行;
        2、当锁被释放时,之前睡眠状态的线程会变成就绪状态,然后内核就会在合适的时间把CPU切换给该线程运行;

        性能开销成本——两次线程上下文切换的成本。


  【当两个线程属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。
        上下切换的耗时大概在几十纳秒到几微秒之间,如果锁住的代码执行时间比较短,可能上下文切换的时间比锁住的代码执行时间还要长】

自旋锁

        通过CPU提供的CAS,在用户态完成加锁和解锁操作,不会主动产生线程上下文切换,所以相比互斥锁来说,会快并且开销小一些。

        加锁过程:查看锁的状态,若是空闲的则执行2;将锁设置为当前线程持有;

特点:       

        1. 使用自旋锁的时候,当发生多线程竞争锁的情况,加锁失败的线程会忙等待,直到拿到锁。忙等待可以通过while循环实现,不过最好是使用CPU提供的PAUSE指令来实现。

        2. 自旋锁利用CPU周期一直自旋直到锁可用。由于一个自选的线程永远不会放弃CPU,因此在单核CPU上,需要抢占式的调度器(不断通过时钟中断一个线程,运行其他线程)

        自旋的时间和被锁住的代码执行的时间成正比关系。

### 自旋锁互斥锁的区别 #### 等待机制 自旋锁通过忙等待(Busy-Wait)持续检查锁的状态,线程在等待期间保持运行状态,不释放CPU资源。互斥锁则在等待锁时主动让出CPU,进入阻塞状态,由操作系统调度唤醒[^3]。 ```c static ALWAYS_INLINE void OSSpinLockLock(volatile OSSpinLock *lock) { do { while (lock->value != 0) { // 忙等待 - 线程一直在CPU上运行 __asm__ volatile ("pause"); } } while (!OSAtomicCompareAndSwap32(0, 1, &lock->value)); } ``` #### 实现原理 自旋锁依赖原子操作(如CAS、Test-And-Set)实现,通常在用户态完成,无需内核介入。互斥锁则依赖操作系统提供的阻塞/唤醒机制(如信号量、条件变量),涉及内核态切换。 #### 性能特点 自旋锁的优点是无上下文切换开销,适合锁持有时间极短的场景(如几纳秒),缺点是长时间等待会浪费CPU资源。互斥锁的优点是等待时不占用CPU,适合锁持有时间较长或不可预测的场景,缺点是上下文切换可能带来较大开销[^3]。 #### 适用场景 自旋锁适用于多核系统,尤其是临界区代码极短(如内核中断处理)、线程不允许休眠的场景(如某些实时系统)以及用户态高性能同步(需结合自适应策略)。互斥锁适用于用户态应用程序,尤其是临界区代码较复杂或耗时较长(如文件操作)、单核CPU环境以及需要避免CPU资源浪费的场景[^3]。 #### 其他差异 自旋锁可能导致优先级反转(高优先级线程空转等待低优先级线程),而互斥锁通常支持优先级继承等机制解决优先级反转问题。此外,自旋锁在单核系统中需禁用中断或配合调度策略,否则可能死锁,而互斥锁适用于所有CPU架构。 #### 性能对比 自旋锁无需保存/恢复上下文,无需切换线程,响应更快,但占用CPU资源。互斥锁需要保存/恢复上下文,需要切换线程,响应较慢,但不占用CPU资源[^5]。 #### 使用场景示例 自旋锁适合短期、快速的操作,如计数器操作: ```c spinlock.lock(); counter++; // 非常快的操作 spinlock.unlock(); ``` 互斥锁适合长时间操作或可能阻塞的操作: ```c mutex.lock(); // 长时间操作或可能阻塞的操作 [self complexOperation]; mutex.unlock(); ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值