1.以中断启用和中断禁止来实现锁
/*
闭锁的第一个操作是禁止中断,这是一个硬件原子操作。然后判断value是否等于FREE,如果是,就表明这个资源没有被其他进程占用,我们就
将其设置为忙,然后开中断。如果value不等于FREE,那么我们循环等待value变为FREE,循环过程中,不断的开中断和关中断,使得在启用
中断和禁止中断之间别的进程能够得以执行。
*/
void lock()
{
cli();
while(value != FREE)
{
sti();
cli();
}
value = BUSY;
sti();
}
void unlock()
{
cli();
value = FREE;
sti();
}
2.以测试指令和设置指令来实现锁
//要求所有的进程在调用unlock之前必须先调用lock,该方法效率强于方法1
int test_and_set(int x)
{
tmp = x;
x = 1;
return tmp;
}
void lock()
{
while(test_and_set(value) == 1); //value的初始值为0
}
void unlock()
{
value = 0;
}
3.以非繁忙等待、中断启用、禁止来实现锁
/*
法1和法2虽然简单、容易理解,但都有一个问题--繁忙等待,繁忙等待浪费资源,并且有可能造成死锁。我们要将其改为不让它繁忙等待,在
其拿不到锁时去睡觉,等待别人叫醒。
*/
void lock()
{
cli();
if(value == FREE)
value = BUSY;
else
{
//把该进程从就绪队列移除,并加入到等待该锁的队列中
}
sti();
}
void unlock()
{
cli();
value = FREE;
if(any task is wating for this lock)
{
//将该进程从该等待队列移除,并将其加入到就绪队列等待调度
value = BUSY;
}
sti();
}
4.以最少繁忙等待、测试与设置来实现锁
void lock()
{
while(test_and_set(guard) == 1);
if(value == FREE)
{
value = BUSY;
guard = 0;
}
else
{
//把该进程从就绪队列移除,并加入到等待该锁的队列中
guard = 0;
//switch to next task(这个不能删掉)
}
}
void unlock()
{
while(test_and_set(guard) == 1);
value = FREE;
if(any task is wating for this lock)
{
//将该进程从该等待队列移除,并将其加入到就绪队列等待调度
value = BUSY;
}
guard = 0;
}