在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的时间

很多原子操作指令都可以做到同步互斥中用户态难以做到的事情。
Hello World社区的界面很美观~希望可以和Hello World一起成长

 
  
  
  
 