2017-04-10 19 views
-2

我只是實現Peterson鎖定算法,但它不能正常工作。
下面是代碼:我是否以錯誤的方式使用內存屏障?

#include <pthread.h> 

typedef struct { 
    volatile bool flag[2]; 
    volatile bool victim; 
} peterson_lock_t; 

void peterson_lock_init(peterson_lock_t &lock) { 
    lock.flag[0] = lock.flag[1] = false; 
    lock.victim = 0; 
} 

void peterson_lock(peterson_lock_t &lock, int id) { 
    lock.victim = id; 
    lock.flag[id] = true; 
    __asm__ __volatile__("" : : : "memory"); 
    while (lock.flag[1 - id] == false && lock.victim != id); 
} 

void peterson_unlock(peterson_lock_t &lock, int id) { 
    lock.flag[id] = false; 
} 

有什麼不對的代碼?

main.cpp中:

#include <stdio.h> 
#include "peterson_lock.h" 

peterson_lock_t lock; 
int count = 0; 

void *routine0(void *arg) { 
    int *cnt = (int *)arg; 
    for (int i = 0; i < *cnt; ++i) { 
     peterson_lock(lock, 0); 
     ++count; 
     peterson_unlock(lock, 0); 
    } 

    return NULL; 
} 

void *routine1(void *arg) { 
    int *cnt = (int *)arg; 
    for (int i = 0; i < *cnt; ++i) { 
     peterson_lock(lock, 1); 
     ++count; 
     peterson_unlock(lock, 1); 
    } 
} 

int main(int argc, char **argv) { 
    peterson_lock_init(lock); 
    pthread_t thread0, thread1; 
    int count0 = 10000; 
    int count1 = 20000; 
    pthread_create(&thread0, NULL, routine0, (void *)&count0); 
    pthread_create(&thread1, NULL, routine1, (void *)&count1); 

    pthread_join(thread0, NULL); 
    pthread_join(thread1, NULL); 

    printf("Expected: %d\n", (count0 + count1)); 
    printf("Reality : %d\n", count); 

    return 0; 
} 

而結果是不正確的:

預計:30000
現實:24304

預計:30000
現實:24316

OS:
Linux的IP-172-31-43-244 3.14.35-28.38.amzn1.x86_64#1 SMP週三03月11日22點五十分37秒UTC 2015年x86_64的x86_64的x86_64的GNU/Linux的

+2

它以什麼方式錯誤地工作? –

+0

@Colin__s我測試這個,結果是錯誤的。我更新'main'的代碼。 – Charles

+2

'volatile'不能作爲內存屏障。使用'std :: atomic'或其他內存圍欄。 _「...這使得易失性對象適合與信號處理程序進行通信,但不能與另一個執行線程進行通信」_源:http://en.cppreference.com/w/cpp/language/cv –

回答

0

雖然條件還需要改進:

while(lock.flag [1 - id] == true & & lock.victim == id) continue; 忙於等待,直到另一個線程鎖定,你是受害者。

Peterson Lock

相關問題