进程同步机制

来源:互联网 发布:c语言标准库函数有多少 编辑:程序博客网 时间:2024/05/18 02:01
原文地址:http://xia-siyu.blog.163.com/blog/static/274830412010911549960/

一、原子操作
所谓原子操作是指不会被线程调度机制打断的操作。
通常所说的原子操作包括对非long和double型的primitive进行赋值以及返回这两者之外的primitive。
原子操作不需要同步机制。
P.S:volatile修饰的long和double型的赋值和返回是原子操作
二、信号量机制
主要同步机制就是PV操作。
P:请求分配一个单元
V:请求释放一个单元
P原语操作的动作:
(1)信号量S-1
(2)若S-1后仍大于等于0,则进程继续进行
(3)若S-1后小于0,则该进程被阻塞后进入该信号对应的队列中,然后转进程调度
V原语操作的动作:
(1)信号量S+1
(2)若S+1后大于0,则进程继续进行
(3)若S+1后小于等于0,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度
PV操作对于每一进程只能进行一次,且必须成对使用,在PV原语执行阶段不允许中断发生。
三、自旋锁
自旋锁是为了保护共享资源提出的一种锁机制。
调用者申请的资源如果被占用,即自旋锁被已经被别的执行单元保持,则调用者一直循环在那里看是否该自旋锁的保持着已经释放了锁
自旋锁是一种比较低级的保护数据结构和代码片段的原始方式,可能会引起以下两个问题;
(1)死锁
试图递归地获取自旋锁必然会引起死锁
(2)过多地占用CPU资源
自旋锁适用于锁使用者保持锁的时间比较短的情况。
如果被保护的共享资源需要在中断上下文访问,必须使用自旋锁。
自旋锁只在内核可抢占或者SMP(多处理器)的情况下才真正需要,在单处理器且内核不可抢占情况下自旋锁所作的操作都是空操作。
四、管程
管程定义了一个数据结构和能为并发进程所执行的一组操作,这组操作能同步进程和改变管程中的数据。
管程形式:
type 管成名 = monitor {
局部变量说明;
条件变量说明;
初始化语句;
define 管程内定义的,管程外可调用的过程或者函数名列表
use 官城外定义的,管程内可调用的过程或者函数名列表
过程名/函数名(形式参数表){
<过程/函数体>
}
......
}
主要操作:
wait():是没有申请到资源的进程等待
signal():唤醒等待队列中的进程
五、会合
(1)调用语句
<进程名称><进程名称>.<入口名称>[参数列表]
例:Buffer.read(a)
将自身放入等待链,唤醒相应进程
(2)接受语句
accept <入口名称><入口名称>[形式参数]
[do <语句列表><语句列表>]
例:accept read (OUT:int a)
do a = buffer【i】;
(3)选择语句
select [when (<布尔表达式><布尔表达式>) do]
<接受语句><接受语句>[<语句序列><语句序列>]
六、分布式系统
时钟同步法。
为每一个进程设置一个逻辑时钟。所谓逻辑时钟,是指能为本地启动的所有活动,赋予一个编号的机构,他
可以用计数器来实现。在系统中,每一个进程都拥有自己的逻辑时钟 c。在一个系统的逻辑时钟系统,应满足条件:
对于任何活动 a(ini)和 b(inj),如果 a->b,则相应的逻辑时钟c(i,a) < b(j,B)。其中i,j表示处于不同物理
位置的进程。为了满足上述条件,必须遵循以下规则:
第一,根据活动发生的先后,赋予每个活动唯一的逻辑时钟值。
第二,若活动 a 是进程 i 发送的一条消息 m,消息 m中应包含一个时间邮戳 T(m)=c(i,a);当接受进程 j在收
到消息时,如果其逻辑时钟 c(j,B)<c(i,a),则应当重置c(j,B)大于或等于c(j,B)。