Moving a thread to another thread while both threads are in use

Viewed 282
// threadMovedFixed.cpp

#include <iostream> 
#include <thread> 
#include <utility>

int main(){ 

  std::thread t([]{std::cout << std::this_thread::get_id() << std::endl;}); 
  std::thread t2([]{std::cout << std::this_thread::get_id() << std::endl;}); 
  
  t.join();
  t = std::move(t2); 
  t.join(); 
  
  std::cout << "\n";
  std::cout << std::boolalpha << "t2.joinable(): " << t2.joinable() << std::endl;

}

I am looking at the following snippet, and it seems there are several issues here.

(1) t2 is being moved to t while t2 while it may be in the middle of executing its lambda. What happens to t2 in this case? Does t2 terminate right away and t re-executes t2's lambda from the the beginning, or does it pick up where t2 left off?

(2) t is receiving t2, but t could be in the middle of its execution of the lambda. What happens here? Does t terminate its own call immediately upon receiving t2?

2 Answers

What happens to t2 in this case?

It will no longer refer to a thread of execution.

Does t2 terminate right away

std::thread object isn't something that can be terminated. It potentially refers to a thread of execution which is something that can conceptually terminate. That thread of execution is not affected by the move. After the move, t refers to the thread of execution instead.

but t could be in the middle of its execution of the lambda.

t has been joined, and therefore it no longer refers to a thread of execution until t2 is assigned to it.

If t was joinable, then std::terminate would be called (which terminates the process).

Please keep in mind that C++ doesn't implement all the multithreading stuff but delegates that to OS. C++ multithreading classes are just wrappers with a convenient interface that follows C++ idioms.

So, there is no problem in moving a running thread to another std::thread object. Otherwise (look on it from another angle) why does std:thread even have a move constructor? Actually all the OS threads are running even without knowing that C++ has a wrapper. The OS thread (e.g. pthread) continue running being wrapped with another object.

Regarding your second question, t is not in the middle of it's execution cause it is already in non-joinable state.

Related