进程互斥的实现方法

软件实现

单标志法

int turn = 0;   // 表示当前允许进入临界区的进程号
// turn 表示的是谦让

P0 进程:
// 进入区
while (turn != 0);// turn 不是0代表当前不该自己进入临界区,那么就一直卡在while循环
// 临界区
critical section;// 退出区
turn = 1;// 自己已经完成了对临界资源的使用,把使用权交给另一个进程
// 剩余区
remainder section;    Ⅳ

P1 进程:
// 进入区
while (turn != 1);// turn 不是1代表当前不该自己进入临界区,那么就一直卡在while循环
// 临界区
critical section;// 退出区
turn = 0;// 自己已经完成了对临界资源的使用,把使用权交给另一个进程
// 剩余区
remainder section;

这个方法是交替访问临界区资源的,所以一旦某个进程不再访问临界区资源,那么就会导致另一个进程也不能访问临界区资源,这样就会造成资源的浪费。违背:空闲让进,让权等待

双标志先检查法

先检查后上锁:

bool flag[2];             // 表示进入临界区意愿的数组
flag[0] = false;        
flag[1] = false;          // 刚开始两个进程都不想进入临界区

P0 进程:
// 进入区
while (flag[1]);// 如果 P1 想要进入, P0 进程就会卡死在这里
flag[0] = true;// P0 表达自己想要使用临界区
// 临界区
critical section;
// 退出区
flag[0] = false;           // P0 已经访问完了临界区资源,更改意愿为:不想访问临界区
// 剩余区
remainder section;

P1 进程:
// 进入区
while (flag[0]);// 如果 P0 想要进入, P1 进程就会卡死在这里
flag[1] = true;// P1 表达自己想要使用临界区
// 临界区
critical section;
// 退出区
flag[1] = false;           // P1 已经访问完了临界区资源,更改意愿为:不想访问临界区
// 剩余区
remainder section;

按照 Ⅰ,Ⅱ,Ⅲ,Ⅳ的顺序执行,则会导致 flag[0] = true, flag[1] = true; 两个进程都会进入临界区,违背:忙则等待,让权等待;原因在于 “检查” 和 “上锁” 两个操作不能一气呵成。

双标志后检查法

先上锁后检查:

bool flag[2];             // 表示进入临界区意愿的数组
flag[0] = false;        
flag[1] = false;          // 刚开始两个进程都不想进入临界区

P0 进程:
// 进入区
flag[0] = true;// P0 表达自己想要使用临界区
while (flag[1]);// 如果 P1 想要进入, P0 进程就会卡死在这里
// 临界区
critical section;
// 退出区
flag[0] = false;           // P0 已经访问完了临界区资源,更改意愿为:不想访问临界区
// 剩余区
remainder section;

P1 进程:
// 进入区
flag[1] = true;// P1 表达自己想要使用临界区
while (flag[0]);// 如果 P0 想要进入, P1 进程就会卡死在这里
// 临界区
critical section;
// 退出区
flag[1] = false;           // P1 已经访问完了临界区资源,更改意愿为:不想访问临界区
// 剩余区
remainder section;

按照 Ⅰ,Ⅱ,Ⅲ,Ⅳ的顺序执行,则会导致 flag[0] = true, flag[1] = true; 两个进程都无法进入临界区,违背:空闲让进,有限等待,让权等待,导致饥饿的现象

Pesterson 算法

单标志法 + + + 双标志后检查法:

bool flag[2];
int turn = 0;

P0 进程:
// 进入区
flag[0] = true;                // 表达自己要用的意愿
turn = 1;                      // 愿意先让给你用
while (flag[1] && turn == 1);  // 对方也想用并且最后是自己谦让的话就让对方用,自己卡死
// 临界区
critical section;
// 退出区
flag[0] = false;               // 自己用完了,进入圣人模式
// 剩余区
remainder section;

P1 进程:
// 进入区
flag[1] = true;                // 表达自己要用的意愿
turn = 0;                      // 愿意先让给你用
while (flag[0] && turn == 0);  // 对方也想用并且最后是自己谦让的话就让对方用,自己卡死
// 临界区
critical section;
// 退出区
flag[1] = false;               // 自己用完了,进入圣人模式
// 剩余区
remainder section;

不遵循:让权等待

硬件实现

中断屏蔽方法

...
关中断;
临界区;
开中断;
...

TestAndSet(TS指令/TSL指令)

// lock = true;  代表上锁
// lock = false; 表示未上锁
bool TestAndSet(bool *lock){
    
    
    bool old;
    old = *lock;   // old用来存放lock原来的值
    *lock = true;  // 无论是否上锁,都上锁
    return old;    // 返回old原来的值
}

// 用 TestAndSet 指令实现互斥的逻辑
while (TestAndSet(&lock));   // 上锁并检查
临界区代码段...
lock = false;     // 解锁
剩余区代码段...

不满足:让权等待

Swap指令(XCHG指令)

// Swap 指令的作用是交换两个变量的值
Swap (bool *a, bool *b){
    
    
    bool temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

// 以下是用 Swap 指令实现互斥的算法逻辑
// lock = true;  代表上锁
// lock = false; 表示未上锁
bool old = true;
while (old == true)
    Swap(&lock, &old);
临界区代码段...
lock = false;
剩余区代码段...

不满足:让权等待

猜你喜欢

转载自blog.csdn.net/qq_52156445/article/details/131726172