Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does std::thread::join guarantee writes visibility

Std::thread::join is said to 'synchronize-with' the joined thread, however synchronization doesnt tell anything about visibility of side effects, it merely governs the order of the visiblity, ie. in following example:

int g_i = 0;
int main()
{
  auto fn = [&] {g_i = 1;};
  std::thread t1(fn);
  t1.join();
  return g_i;
}

Do we have any guarantee in the c++ standard that this program will always return 1?

like image 976
Salamander86 Avatar asked Jul 22 '20 09:07

Salamander86


People also ask

Is thread join thread safe?

It is not thread safe. If you have more than one thread that can call your snippet at any time, you may experience a race condition. The only real way to protect against this is by wrapping your snippet in an std::mutex shared by the threads calling said snippet.

What does std :: thread join do?

std::thread::join. Blocks the current thread until the thread identified by *this finishes its execution. The completion of the thread identified by *this synchronizes with the corresponding successful return from join() .

What happens if thread join is not called?

Join is a synchronization method that blocks the calling thread (that is, the thread that calls the method) until the thread whose Join method is called has completed. Use this method to ensure that a thread has been terminated. The caller will block indefinitely if the thread does not terminate.

Is std :: thread copyable?

4) The copy constructor is deleted; threads are not copyable. No two std::thread objects may represent the same thread of execution.


1 Answers

[thread.thread.member]:

void join();
Effects: Blocks until the thread represented by *this has completed.
Synchronization: The completion of the thread represented by *this synchronizes with the corresponding successful join() return.

Since the completion of the thread execution synchronizes with the return from thread::join, the completion of the thread inter-thread happens before the return:

An evaluation A inter-thread happens before an evaluation B if
A synchronizes with B

and thus happens before it:

An evaluation A happens before an evaluation B (or, equivalently, B happens after A) if:
A inter-thread happens before B

Due to (inter-thread) happens before transitivity (let me skip copypasting the whole definition of inter-thread happens before to show this), everything what happened before the completion of the thread, including the write of the value 1 into g_i, happens before the return from thread::join. The return from thread::join, in turn, happens before the read of value of g_i in return g_i; simply because the invocation of thread::join is sequenced before return g_i;. Again, using the transitivity, we establish that the write of 1 to g_i in the non-main thread happens before the read of g_i in return g_i; in the main thread.

Write of 1 into g_i is visible side effect with respect to the read of g_i in return g_i;:

A visible side effect A on a scalar object or bit-field M with respect to a value computation B of M satisfies the conditions:
A happens before B and
— there is no other side effect X to M such that A happens before X and X happens before B.
The value of a non-atomic scalar object or bit-field M, as determined by evaluation B, shall be the value stored by the visible side effect A.

Emphasis of the last sentence is mine and it guarantees that the value read from g_i in return g_i; will be 1.

like image 57
Language Lawyer Avatar answered Sep 19 '22 03:09

Language Lawyer