操作系统学习笔记 原来自旋锁还可以这样实现!

在java中我们知道对线程使用CAS(compare and swap)来实现自旋锁,在没有学习操作系统之前,我以为这是唯一一种方法了。但是今天学到了操作系统中的同步互斥,终于明白了原来CAS、TS、Swap这些都是硬件提供的原子操作罢了!不仅CAS可以实现自旋锁,TS(Test and Set)同样可以!

临界区

  • 临界区

进程中访问临界资源的一段需要互斥执行的代码

  • 进入区

    • 检查可否进入临界区的一段代码
    • 如可进入,设置相应“正在访问临界区”标志
  • 退出区

    • 清楚“正在访问临界区”标志
  • 剩余区

    • 代码的剩余部分

临界区的访问规则

  • 空闲则入
    • 没有进程在临界区时,任何进程可进入
  • 忙则等待
    • 有进程在临界区时,其他进程均不能进入临界区
  • 有限等待
    • 等待进入临界区的进程不能无限期等待
  • 让权等待(可选)
    • 不能进入临界区的进程,应释放CPU(如转换到阻塞状态)

临界区的实现方法

  • 禁用中断
  • 软件方法
  • 更高级的抽象方法

方法3:高级抽象的同步方法

  • 硬件提供了一些同步原语
    • 中断禁用,原子操作指令
  • 操作系统提供更高级的变成抽象来简化进程同步
    • 例如:锁、信号量
    • 用硬件原语来构建

锁lock

  • 锁是一个抽象的数据结构
    • 一个二进制变量(锁定/解锁)
    • Lock::Acquire()
      • 锁被释放前一直等待,然后得到锁
    • Lock::Release()
      • 释放锁,唤醒任何等待的进程

原子操作指令

  • 现代CPU体系结构都提供了一些特殊的原子操作指令

  • 测试和置位(Test-and-set)指令

    • 从内存单元中读取值
    • 测试该值是否为1(然后返回真或假)
    • 内存单元值设置为1
使用TS指令实现自旋锁
class Lock{
    int value = 0;
}
Lock::Acquire() {
    while( test-and-set(value))
        ; //spin
}
Lock::Release() {
    value = 0;
}

如果锁被释放,那么TS指令读取0并将值设置为1

  • 锁被设置为忙并且需要等待完成

如果锁处于忙状态,那么TS指令读取1并将值设置为1

  • 不改变锁的状态并且需要循环

它的问题是线程在等待的时候也要消耗CPU的时间

在这里插入图片描述
很多原子操作指令都可以做到同步互斥中用户态难以做到的事情。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值