joinsynchronizes with the thread that is calling join. That is, everyone writes that Amake will become visible to Bwhen it Binvokes A.join().
You can think of it as Aexecution std::atomic_thread_fence(memory_order_release)as it completes, and Bexecution std::atomic_thread_fence(std::memory_order_acquireas it merges A.
Does thread B require a memory barrier?
Yes, but they are implicit in join, and you do not need to write them.
Is it likely that when the OS API says "thread A is finished", the changes in memory that it changed are not yet visible to other threads?
, join, , . std::condition_variable std::atomic_thread_fence(std::memory_order_acquire);