I've been reading up on the C++ memory model and memory ordering and watched Herb Sutter's 2 presentations on atomics and it seems like the in usual case when you have shared access to some data from different threads you need to synchronize them using acquire/release semantics. If one is using an atomic simply to signal some event like telling a thread to stop and not "publishing any data" do you need acquire release semantics? If I'm understanding acquire/release semantics correctly then it seems like the acquire in threadLoop() achieves nothing because it doesn't ensure that the write to the atomic thread_running_ from the destructor is actually made visible before the load. It seems to just make sure that all previous memory accesses are visible after the load and before entering the loop which doesn't seem necessary in this case. I'm just asking this for an understanding of what the weakest memory ordering I would need in this case would be, I realize this isn't necessarily going to make a performance difference in this case and is probably un-wise.
class ThreadedRunLoopClass {
public:
ThreadedRunLoopClass : thread_running_(false), loop_counter(0) {}
~ThreadedRunLoopClass();
void run();
private:
void threadLoop();
std::thread run_loop_thread_;
std::atomic_bool thread_running_;
std::atomic_uint loop_counter_;
};
ThreadedRunLoopClass::~ThreadedRunLoopClass() {
// I'm not sure if this can use std::memory_order_relaxed
// b/c I wonder if it can be moved below the if block
// and cause a deadlock
thread_running_.store(false, std::memory_order_release);
if (run_loop_thread_.joinable()) {
run_loop_thread_.join();
}
}
void ThreadedRunLoopClass::run() {
thread_running_.store(true, std::memory_order_release);
run_loop_thread_ = std::thread([this] { threadLoop(); });
}
void ThreadedRunLoopClass::threadLoop() {
// This seems to me like it could use std::memory_order_relaxed
while(thread_running_.load(std::memory_order_acquire)) {
loop_counter_++;
}
}
int main() {
{
ThreadedRunLoopClass looper{};
looper.run();
// ...
}
}
Aucun commentaire:
Enregistrer un commentaire