2

[Hereinafter, C++ terms]

I have a thread A and thread B that share access to the integer value P. Thread A initializes this value and updates it while running. Then thread A completes. Thread B waits for thread A to complete (standard OS API call, whatever OS is used) and wants to read P.

Does thread B need a memory barrier to read a coherent, last set by thread A, value of P? Is there a possibility that when OS API says "thread A finished", the changes of memory it modified are not visible to other threads yet?

Note that there only one thread writing the value here, which may or may not distinguish this question from "Is there an implicit memory barrier with synchronized-with relationship on thread::join?" asked before. My gut feeling tells me the answer should be the same, but...

nsh
  • 380
  • 3
  • 9
  • 1
    This sounds like a job for `std::future. – Pete Becker Mar 29 '17 at 19:17
  • From reading [this](https://timsong-cpp.github.io/cppwp/thread.thread.member#4) , I'd say that yes - .join() does synchronize, and you don't need a memory barrier. But that text is not written for normal mortals to interpret, so I'll leave the answering to someone else. Maybe also a duplicate of http://stackoverflow.com/questions/12444891/are-memory-barriers-required-when-joining-on-a-thread?rq=1 – nos Mar 29 '17 at 19:20

1 Answers1

1

join synchronizes with the thread that calls join. That is, all writes that A makes will become visible to B when B calls A.join().

You can think of this as A executing std::atomic_thread_fence(memory_order_release) as it finishes and B executing std::atomic_thread_fence(std::memory_order_acquire as A joins.

Does thread B need a memory barrier

Yes, but they are implicit in join and you do not have to write them.

Is there a possibility that when OS API says "thread A finished", the changes of memory it modified are not visible to other threads yet?

Threads other than the caller of join will need additional synchronization, e.g. std::condition_variable or std::atomic_thread_fence(std::memory_order_acquire);

Pubby
  • 51,882
  • 13
  • 139
  • 180