《操作系統概念》筆記--硬件同步與互斥鎖

硬件同步

test_and_set()

boolean test_and_set(boolean *target){
    boolean rv = *target;
    *target = true;

    return rv;
}

先聲明一個布爾變量lock,初始化爲false。
當沒有進程在臨界區內時,lock爲false, 當有進程在臨界區內時,lock爲true。
當一個進程想要進入臨界區時,它會先調用test_and_set(),test_and_set()返回lock的原始值,並將lock賦值爲true。
若返回值爲false,則該進程可進入臨界區
若返回值爲true,則表示有進程在臨界區,所以該進程需循環調用test_and_set(),直到沒有進程在臨界區內。
採用指令test_and_set的進程實現:

do{
    while(test_and_set(&lock));
    
    lock = false;
}while(true);

compare_and_swap()

int compare_and_swap(int *value, int expected, int new_value){
    int temp = *value;
    
    if(*value == expected)
        *value = new_value;
    
    return temp;
}

指令compare_and_swap()需要三個操作數。
首先聲明一個全局布爾變量lock,初始化爲0。
當臨界區內有進程時,lock值爲1,臨界區內沒有進程時,lock值爲0
當一個進程需要進入臨界區時,首先調用compare_and_swap(&lock, 0, 1),中間爲期望值,最後面爲新增值,返回lock原始值。
如果沒有進程在臨界區,lock值爲0,調用之後,因爲lock值等於期待值0,lock值變爲1,並且返回0,於是進入臨界區。
如果有進程在臨界區,lock值爲1,調用之後,lock值不等於期待值,返回值爲1不等於0,於是循環調用等待。
採用指令compar_and_swap()的指令實現:

do{
    while(compare_and_swap(&lock, 0, 1) != 0);

    lock = 0;

}while(true);

滿足有限等待

上述並不滿足有限等待條件,下面實現滿足有限等待的test_and_set()
進程共用的數據結構爲:
boolean waiting[n]
boolean lock
這些結構初始化爲false。
只有waiting[i] == false 或者 key == false時,進程pi才能進入臨界區

do{

waiting[i] = true;
key = true;
while(waiting[i] && key)
    key = test_and_set(&lock);
waiting[i] = false;

//當隊列中下一個進程wainting爲true,時,表示要進入臨界區,於是得到j
j = (i+1) % n;  
while((j!= i) && !waiting[j])
    j = (j+1)%n;

//把lock設爲false或者把waiting[j]設爲false,都能使j進程推出循環等待,進入臨界區。
if(j == i)
    lock = false;
else
    waiting[j] = false;

}while(true);

當wainting[i] == true時,代表該進程想進入臨界區。
key初始化爲true,當臨界區沒有進程時,lock爲false,調用test_and_set,key設爲false,lock設爲true,該進程進入臨界區。
當臨界區有進程時,lock爲true,key一直爲true,於是循環調用等待,直到進程離開臨界區。
當該進程離開臨界區時,wainting[i]設爲false,表示不想進入臨界區。

#互斥鎖
每個互斥鎖有一個布爾變量available,它的值表示鎖是否可用。
如果瑣是可用的,那麼調用acquire()會成功,並且鎖不再可用
當一個進程試圖獲取不可用的鎖時,它會阻塞,知道鎖被釋放。

acquire(){
    while (!available);
    
    availablle = false;
}
release(){
    available = true;
}

互斥鎖的缺點是需要忙等待。

當有一個進程在臨界區中,任何其他進程在進入臨界區時必須連續循環地調用acquire()。

** 考慮如何使用原子硬件指令實現互斥鎖。假設互斥鎖的結構如下:

typedef struct{
    int available;
}lock;

當available爲0時,表示鎖可用;當available爲1時,表示鎖不可用。通過這個struct,說明如何採用指令test_and_set()和compare_and_swap()來實現如下函數,一定包括任何可能必要的初始化:

  • void acquire(lock *mutex)
void acquire(lock *mutex){
    while(test_and_set(*mutex.available));
}
void acquire(lock *mutex){
    while(compare_and_swap(*mutex.available, 0, 1) != 0);
}
  • void release(lock *mutex)
void release(lock *mutex){
    *mutex.available = 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章