c++ - C++11 memory_model_relaxed和memory_order_seq_cst的关系
问题描述
嗨,我想了解无锁工作窃取出队实现。目前,我正在阅读谷歌的灯丝here的一种实现。我最关心的是窃取操作。
template <typename TYPE, size_t COUNT>
TYPE WorkStealingDequeue<TYPE, COUNT>::steal() noexcept {
do {
// mTop must be read before mBottom
int32_t top = mTop.load(std::memory_order_seq_cst);
// mBottom is written concurrently to the read below in pop() or push(), so
// we need basic atomicity. Also makes sure that writes made in push()
// (prior to mBottom update) are visible.
int32_t bottom = mBottom.load(std::memory_order_acquire);
if (top >= bottom) {
// queue is empty
return TYPE();
}
// The queue isn't empty
TYPE item(getItemAt(top));
if (mTop.compare_exchange_strong(top, top + 1,
std::memory_order_seq_cst,
std::memory_order_relaxed)) {
// success: we stole a job, just return it.
return item;
}
// failure: the item we just tried to steal was pop()'ed under our feet,
// simply discard it; nothing to do.
} while (true);
}
我想知道将初始 mtop.load 内存顺序替换为 memory_order_relaxed 并将随后的 mBottom.load 内存顺序替换为 memory_order_seq_cst 是否正确。这仍然应该保留 mtop.load 和 mBottom.load 顺序对吗?memory_order_seq_cst 标志仍然应该防止 memory_order_relaxed 通过加载操作被重新排序,对吗?
解决方案
您应该根据允许发生内存操作以保持正确性的顺序以及这些顺序如何影响线程间同步来对代码进行推理。C++std::memory_order
标准允许程序员表达这样的约束,并让编译器发出必要的内存栅栏来实现这些约束。
代码已经准确地表达了它需要做的事情:mTop.load()
在之前排序并将in与inmBottom.load()
同步。mBottom.store()
push()
mBottom.load()
steal()
推荐阅读
- google-data-studio - Google Data Studio 在折线图上隐藏数据
- phpstorm - PhpStorm 不输入提示魔法常量
- python-3.x - python 3上的ctypes函数调用失败
- r - R - 循环多个变量 group_by
- reactjs - React Router v5 嵌套路由在单独的组件中
- reactjs - 将 Salesforce 实时代理聊天添加到 React Js
- kubernetes - 如何查询 Kubernetes 节点可用的总内存
- java - 为什么我的 jar 不包含 gurobi.jar?
- javascript - TypeError:props.items.map 不是函数
- microsoft-edge - 如何获取 Microsoft Edge 扩展的包系列名称(PFN)?