如何解决强制释放和获取排序以获取和添加加载/存储
所以我试图以这样一种方式实现作者和读者方法,我总是希望读者读取作者最后一次写入的值,从而在写入之后进行读取。对于这个特定的例子,我尝试使用一个非常简单的固定大小队列,它有两个指针,_enqPtr
和 _deqPtr
。这些都是 std::atomic<size_t>
表示元素入队或出队的下一个索引。我正在使用的完整代码如下
class Queue {
public:
Queue(size_t size): _enqPtr(0),_deqPtr(0),_size(size),_data(new std::atomic<long>[_size])
{
for (int i = 0; i < _size; ++i)
{
_data[i].store(0);
}
}
bool enqueue(long val) {
size_t place = _enqPtr.fetch_add(1,std::memory_order_relaxed);
if (place >= _size)
return false;
_data[place].store(val,std::memory_order_release); // DESIRED TO BE BEFORE
return true;
}
bool dequeue(long& val) {
size_t place = _deqPtr.fetch_add(1,std::memory_order_relaxed);
size_t enq = _enqPtr.load();
if (place >= _size)
return false;
if (place >= enq) {
// went too far
_deqPtr.store(enq - 1);
return false;
}
val = _data[place].load(std::memory_order_acquire); // DESIRED TO BE AFTER
assert(val != 0); // keeps catching this,despite acquire / release.
return true;
}
private:
std::atomic<size_t> _enqPtr;
std::atomic<size_t> _deqPtr;
size_t _size;
std::atomic<long>* _data;
};
fetch_add
调用有助于每个调用 enqueue
或 dequeue
的线程获得自己的索引。然而,我遇到的问题似乎是,一个线程调用 enqueue
并调用 fetch_add
,但在它可以存储它的值之前,另一个线程调用 dequeue
并完成调用,从而读取空值或非值(在本例中为零)。
我用来测试的线程代码如下:
class QueueTester {
public:
QueueTester(size_t queueSize,size_t threadCount):
_threadCount(threadCount),_threads(new std::thread[_threadCount]),_queue(queueSize)
{}
void run() {
for (int i = 0; i < _threadCount; ++i)
{
if (i % 2 == 0) {
_threads[i] = std::thread([this]{
long k = 1;
while (_queue.enqueue(k)) {
k = k == 0 ? 1 : k + 1;
}
});
} else {
_threads[i] = std::thread([this]{
long k = 1;
while (_queue.dequeue(k));
});
}
}
for (int i = 0; i < _threadCount; ++i)
{
_threads[i].join();
}
}
private:
size_t _threadCount;
std::thread* _threads;
Queue _queue;
};
我需要在内存排序和围栏方面进行哪些调整,以便 val = _data[place].load(std::memory_order_acquire);
始终在 _data[place].store(val,std::memory_order_release);
之后/从 {{1}} 加载?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。