操作系统(6)——同步

同步的唯一问题就是共享变量的竞态,我们使用锁来保护操作共享变量的代码段,从而保证操作共享变量时候不会被中断。

锁的实现的硬件基础就是cas和tas,所有锁(信号量,互斥锁)都是通过cas和tas实现的。

一个进程在它指令流上的任意一点都会可能会被中断,并且转而执行其他进程。

临界区:
多个线程访问的数据结构的代码区域。

赋值操作,需要将值取到寄存器中,然后修改,再放回。被打断会有问题。
所以在临界区,不同进程的转换,因为非原子操作的中断转而执行其他进程,会导致竞争冲突。

单线程非抢占式内核的数据结构基本不会存在竞态问题,而抢占式的数据结构需要设计避免。

抢占式的优点:因为不会有进程运行任意长的时间。

临界区问题的解决方案必须满足下面三个条件:

(1)进程互斥。

(2)进步(需要选出谁来进入临界区)

(3)有限等待:没有进程一直想进入但无限等待。

忙等待:即自旋锁,一直会请求获得锁(一个while)

同步方案

经典的基于软件的临界区的解决方案:Peterson解决方案

用到的数据结构包括(i=0,j=1):
int turn;//i为i进入,j为j进入。
boolean flag[2];//flag[i]为i能否进入,flag[j]为j能否进入。

do{//这是线程i想要进入临界区
	flag[i]=true;
	turn=j;//表示轮到j
	while(flag[j]&&turn==j);
	
	//如果flag[j]为真,表示j也有进入的打算,并且如果trun为j,那么表示线程i设置turn在线程j设置trun后实现的,那么线程i进入忙等待。当线程     j执行完成后,flag[j]为false,忙等待结束,开始执行线程i。

	临界区
	flag[i]=false;
	
}while(true)
硬件同步

对于单处理器环境,临界区的问题只要在修改共享变量时候,禁止中断就行了。

但是多处理不行,因为性能下降很大。

原子指令:通过硬件实现的原子式操作,指令执行中不能中断

就是tas和cas
(1)test_and_set(boolean target)

如果target为true,则能set。

(2)compare_and_swap(int* old_value,int expected,int new_value)

如果old_value为expected,那么old_value=new_value;

互斥锁

使用硬件实现的软件工具来解决方案,最简单的工具就是互斥锁,就是使用互斥锁来保护临界区。

do{

acquire_mutex();

临界区;

release_mutex();

剩余区;

}while()

acquire是通过自旋实现的,会浪费一个进程。

优点:如果使用锁的时间很短,将不需要上下文切换。

信号量

包装硬件指令实现的软件工具。其作用是保证临界区代码只由一个线程执行。

(1)一个信号量,除了初始化,只有两个原子操作wait()和signal()来访问。

wait是一个自旋的–操作

wait(s){

while(s<=0)

{};

s--

}

signal(s){

s++

}

(2)计数信号量和二进制信号量(只能为1或者0)

计数信号量可以用来控制访问具有多个实例的各种资源,信号量的初始值为可用资源数,使用一个就减去1。

二进制信号量可以当作互斥锁。

(3)通过等待队列实现计数阻塞,而不是自旋

只需要一个链表实现的等待队列,wait如果s<0,那么将pcb添加到等待对列中。

signal()会wakeup()唤醒队列进程。

死锁和饥饿

具有等待队列信号量会导致这种情况:两个或多个进程无限等待一个事件,而该事件只能由等待对列中的事件释放。

这就是死锁。

饥饿是由于优先级LIFO队列导致的。

经典问题

(1)读者-作者问题(读写锁)

(2)哲学家就餐问题

(3)有界缓冲问题

管程

因为直接操作信号量可能会因为用户的使用错误而导致时许错误,管程是一种(Abstract Data Type,ADT)封装了数据以及操作,保证不会因为使用而错误。

管程的实现是通过信号量的操作的封装来实现的。

管程确保只有一个进程在管程内部处于活动。进程进入管程前执行wait(mutex),离开后执行signal();

条件变量:信号量。对于信号量只有wait()和signal()可以操作。

设计细节:当有多个进程wait(),而有一个进程signal(),那么谁来获得执行权呢?
可以使用一个FCFS队列。
也可以使用优先级,在wait(优先级),优先级考前的先执行。

synchromized就是一个管程的实现。

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值