【发布时间】:2020-05-21 21:56:26
【问题描述】:
我正在尝试使用原子在 C++ 中实现 MCS 锁。但不幸的是,线程陷入了僵局。一个线程在acquire方法中等待flag变为false,而第二个线程在release方法中卡在do while循环中。所以问题一定是原子地存储/加载下一个节点。任何想法如何调试这个或我做错了什么?
这是我目前所拥有的:
#include <atomic>
#include <iostream>
#include <omp.h>
struct qnode {
std::atomic<qnode *> next;
std::atomic<bool> wait;
};
class mcs_lock {
std::atomic<qnode *> tail;
public:
void acquire(qnode *p) {
p->next.store(nullptr);
p->wait.store(true);
qnode *prev = tail.exchange(p, std::memory_order_acq_rel);
if (prev) {
prev->next.store(p, std::memory_order_release);
/* spin */
while (p->wait.load(std::memory_order_acquire))
;
}
}
void release(qnode *p) {
qnode *succ = p->next.load(std::memory_order_acquire);
if (!succ) {
if (tail.compare_exchange_strong(p, nullptr, std::memory_order_acq_rel))
return;
do {
succ = p->next.load(std::memory_order_acquire);
} while (succ == nullptr);
}
succ->wait.store(false, std::memory_order_release);
}
};
int main() {
mcs_lock lock;
qnode p;
int counter = 0;
#pragma omp parallel for default(none) private(p) shared(lock, counter)
for (int i = 0; i < 100000; i++) {
lock.acquire(&p);
++counter;
lock.release(&p);
}
std::cout << "counter=" << counter << "\n";
return 0;
}
【问题讨论】:
标签: c++ multithreading locking openmp