【发布时间】:2017-10-11 06:00:14
【问题描述】:
是否可以使用std::memory_order_relaxed 作为跳过标志,如iterate:
constexpr static const std::size_t capacity = 128;
std::atomic<bool> aliveness[capacity];
T data[capacity]; // immutable/atomic/etc.
template<class Closure>
void iterate(Closure&& closure){
for(std::size_t i = 0; i<capacity; i++){
if (!aliveness[i].load(std::memory_order_relaxed)) continue;
closure( data[i] );
}
}
void erase(std::size_t index){
aliveness[index].store(false, std::memory_order_relaxed);
}
或者我应该使用 release/acquire 来代替?
aliveness[i] 可能会再次“活着”。
iterate 和 erase 同时从多个线程调用。考虑data immutable/atomic/synchronized 在其他一些外部锁下。
【问题讨论】:
-
你说“可以吗”是什么意思?
-
为什么
size是原子的,为什么你要在for循环的每个循环迭代中重新读取它(使用默认的 seq_cst 加载)? -
@PeterCordes 更新为更简单的情况。
-
通过询问“是否可以”,我的意思是 - 如果在一个线程中执行
erase,那么另一个线程是否iterate会看到该标志变为假;以及多久。是否有可能我们在一个线程中调用erase,但另一个线程没有看到该标志发生变化?
标签: c++ multithreading stdatomic memory-barriers