-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的
它以什麼方式錯誤地工作? –
@Colin__s我測試這個,結果是錯誤的。我更新'main'的代碼。 – Charles
'volatile'不能作爲內存屏障。使用'std :: atomic'或其他內存圍欄。 _「...這使得易失性對象適合與信號處理程序進行通信,但不能與另一個執行線程進行通信」_源:http://en.cppreference.com/w/cpp/language/cv –