我是否以错误的方式使用内存屏障?

时间:2017-04-10 10:17:02

标签: c++

我只是简单地实现了Peterson Lock算法,但它无法正常工作 这是代码:

#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 Wed Mar 11 22:50:37 UTC 2015 x86_64 x86_64 x86_64 GNU / Linux

1 个答案:

答案 0 :(得分:0)

虽然条件也需要改善:

while(lock.flag [1 - id] == true&amp;&amp; lock.victim == id) 继续; 忙着等到另一个线程锁定你是你的受害者。

Peterson Lock