操作系统学习笔记(8) 互斥和同步的实现算法
2010-12-31 11:24
381 查看
============================
进程互斥与同步:
如何协调多个进程对资源的竞争和共享?
如何解决多个进程因为竞争资源而出现执行结果异常,甚至导致系统的不稳定、失效等问题?
采用多道程序并发设计技术的操作系统对诸多进程的并发控制是非常重要的。
并发控制:
(竞争资源)
1。并发进程竞争使用同一资源时,他们之间就会发生冲突。
2。不能同时使用临界资源,必须互斥使用。
3。实现互斥,就必须有阻塞。
4。被阻塞进程永远得不到申请的资源,就是死锁。
临界区使用原则:
1。忙则等待。
2。有限等待。(不能无限制的占据每个临界资源,让临界区外的进程无限等待)
3。空闲让进。
4。让权等待。(不能在临界区内长时间内阻塞等待某个事件)
竞争资源:
(饥饿)
并发控制:
(共同协作)
要保证写操作互斥地进行。
并发控制:
(通信协作)
进程的互斥与同步的解决策略:
1。软件方法(进程自己执行相应的程序指令,很难正确控制进程同步与互斥,增加系统开销。)
2。硬件方法(屏蔽中断等,硬件束缚条件)
3。信号量方法*
4。管程方法
5。消息传递方法
软件方法:
。Dekker算法、Peterson算法
初步设想:轮流进入临界区
var turn:0,1//共享全局变量
============P0=================
while(turn != 0){
nothing;
}
<临界区>
turn = 1;
==============P1===============
while(turn != 1){
nothing;
}
<临界区>
turn = 0;
分析:初步设想
问题1:“忙等”现象。
问题2:临界区不能充分利用,严重影响进程进度,降低系统性能。
问题3:进程没有修改turn 的值,将影响到其他进程推进。
修改算法:
1。设置临界区状态
var flag = array[0,1]:ture|false
============P0===============
while(flag[1]){
}
flag[0] = true;
<临界区>
flag[0] = false;
=============P1================
while(flag[0]){
}
flag[1] = ture;
<临界区>
flag[1] = false;
分析:这种算法不能实现互斥。
第二次改进:
============P0===============
flag[0] = true;
while(flag[1]){
}
<临界区>
flag[0] = false;
=============P1================
flag[1] = ture;
while(flag[0]){
}
<临界区>
flag[1] = false;
分析:死锁。
第三次改进:
============P0===============
flag[0] = ture;
while(flag[1]){
flag[0] = false;
<延迟一段时间>;
flag[0] = true;
}
<临界区>;
flag[0] = false;
=============P1================
flag[1] = ture;
while(flag[0]){
flag[1] = false;
<延迟一段时间>;
flag[1] = ture;
}
<临界区>;
flag[1] = false;
分析:僵局。
Dekker算法:
var flag[2] = {true, false}; //临界区状态
var turn: 0,1 //进入临界区的顺序
============P0==============
flag[0] = ture;
while(flag[1]){
if(turn = 1){
flag[0] = false;
while(turn = 1){
}
flag[0] = true;
}
}
<临界区>;
turn = 1;
flag[0] = false;
============P1==============
flag[1] = ture;
while(flag[0]){
if(turn = 0){
flag[1] = false;
while(turn = 0){
}
flag[1] = true;
}
}
<临界区>;
turn = 0;
flag[1] = false;
互斥与同步解决方法:(硬件方法)
1。屏蔽中断:
代价太大
2。专用机器指令:
testset指令
boolean testset(int i)
{
if(i = 0){
i = 1;
return true;
}else
return false;
}
P(int i)
{
while(testset(bolt)){
do nothing;
}
<临界区>;
bolt = 0;
}
int main()
{
bolt = 0;
P(1);
P(2);
...
P(n);
return 0;
}
exchange指令:
procedure exchange(register r, memory m)
{
//交换变量。
}
procedure P(int i)
{
int key;
while(true){
key = 1;
while(key = 1){
exchange(key, bolt);
}
<临界区>;
exchange(key, bolt);
}
}
int main()
{
bolt = 0;
P(1);
P(2);
...
P(n);
return 0;
}
分析:”忙等“仍然存在,可能出现“饥渴”现象。可能出现死锁现象。
进程互斥与同步:
如何协调多个进程对资源的竞争和共享?
如何解决多个进程因为竞争资源而出现执行结果异常,甚至导致系统的不稳定、失效等问题?
采用多道程序并发设计技术的操作系统对诸多进程的并发控制是非常重要的。
并发控制:
(竞争资源)
1。并发进程竞争使用同一资源时,他们之间就会发生冲突。
2。不能同时使用临界资源,必须互斥使用。
3。实现互斥,就必须有阻塞。
4。被阻塞进程永远得不到申请的资源,就是死锁。
临界区使用原则:
1。忙则等待。
2。有限等待。(不能无限制的占据每个临界资源,让临界区外的进程无限等待)
3。空闲让进。
4。让权等待。(不能在临界区内长时间内阻塞等待某个事件)
竞争资源:
(饥饿)
并发控制:
(共同协作)
要保证写操作互斥地进行。
并发控制:
(通信协作)
进程的互斥与同步的解决策略:
1。软件方法(进程自己执行相应的程序指令,很难正确控制进程同步与互斥,增加系统开销。)
2。硬件方法(屏蔽中断等,硬件束缚条件)
3。信号量方法*
4。管程方法
5。消息传递方法
软件方法:
。Dekker算法、Peterson算法
初步设想:轮流进入临界区
var turn:0,1//共享全局变量
============P0=================
while(turn != 0){
nothing;
}
<临界区>
turn = 1;
==============P1===============
while(turn != 1){
nothing;
}
<临界区>
turn = 0;
分析:初步设想
问题1:“忙等”现象。
问题2:临界区不能充分利用,严重影响进程进度,降低系统性能。
问题3:进程没有修改turn 的值,将影响到其他进程推进。
修改算法:
1。设置临界区状态
var flag = array[0,1]:ture|false
============P0===============
while(flag[1]){
}
flag[0] = true;
<临界区>
flag[0] = false;
=============P1================
while(flag[0]){
}
flag[1] = ture;
<临界区>
flag[1] = false;
分析:这种算法不能实现互斥。
第二次改进:
============P0===============
flag[0] = true;
while(flag[1]){
}
<临界区>
flag[0] = false;
=============P1================
flag[1] = ture;
while(flag[0]){
}
<临界区>
flag[1] = false;
分析:死锁。
第三次改进:
============P0===============
flag[0] = ture;
while(flag[1]){
flag[0] = false;
<延迟一段时间>;
flag[0] = true;
}
<临界区>;
flag[0] = false;
=============P1================
flag[1] = ture;
while(flag[0]){
flag[1] = false;
<延迟一段时间>;
flag[1] = ture;
}
<临界区>;
flag[1] = false;
分析:僵局。
Dekker算法:
var flag[2] = {true, false}; //临界区状态
var turn: 0,1 //进入临界区的顺序
============P0==============
flag[0] = ture;
while(flag[1]){
if(turn = 1){
flag[0] = false;
while(turn = 1){
}
flag[0] = true;
}
}
<临界区>;
turn = 1;
flag[0] = false;
============P1==============
flag[1] = ture;
while(flag[0]){
if(turn = 0){
flag[1] = false;
while(turn = 0){
}
flag[1] = true;
}
}
<临界区>;
turn = 0;
flag[1] = false;
互斥与同步解决方法:(硬件方法)
1。屏蔽中断:
代价太大
2。专用机器指令:
testset指令
boolean testset(int i)
{
if(i = 0){
i = 1;
return true;
}else
return false;
}
P(int i)
{
while(testset(bolt)){
do nothing;
}
<临界区>;
bolt = 0;
}
int main()
{
bolt = 0;
P(1);
P(2);
...
P(n);
return 0;
}
exchange指令:
procedure exchange(register r, memory m)
{
//交换变量。
}
procedure P(int i)
{
int key;
while(true){
key = 1;
while(key = 1){
exchange(key, bolt);
}
<临界区>;
exchange(key, bolt);
}
}
int main()
{
bolt = 0;
P(1);
P(2);
...
P(n);
return 0;
}
分析:”忙等“仍然存在,可能出现“饥渴”现象。可能出现死锁现象。
相关文章推荐
- 操作系统学习笔记(9) 互斥和同步的信号量算法
- 操作系统学习笔记(10) 互斥和同步的经典问题
- 操作系统学习笔记(13) 互斥与同步的经典问题 -哲学家进餐问题
- 孙鑫VC学习笔记:第十五讲 (三) 增加互斥条件实现线程同步
- 算法(第四版)学习笔记之java实现可以动态调整数组大小的栈
- 算法:C语言实现第三章第一节学习笔记
- [算法学习笔记]基于最大堆实现最大优先队列
- 数据结构与算法学习笔记——链表部分实现(数组形式)
- 8大内部排序算法学习笔记--(2)快速排序 Java实现
- redux-form的学习笔记二--实现表单的同步验证
- 《PID控制算法的C语言实现》学习笔记
- 算法导论学习笔记(1)——快排中hoarePartition的实现(问题已解决)
- 操作系统学习笔记:文件系统实现
- 算法(第四版)学习笔记之java实现堆排序
- 深度学习笔记(二):简单神经网络,后向传播算法及实现
- 《Orange'S:一个操作系统的实现》学习笔记(四)
- 算法(第四版)学习笔记之java实现选择排序
- linux 系统编程-学习笔记9--线程的同步互斥锁、读写锁/select/poll
- 操作系统学习笔记:文件系统实现
- 【数据结构与算法学习笔记】PART2 向量(接口与实现,可扩充向量,无序向量,有序向量)