Table of Contents

C - C++ Threads - Transfer ownership of threads at runtime

std::move can be called to move the ownership of the underlying thread resource from one std::thread object to another.


Problem

#include <iostream>
#include <string>
#include <thread>
#include <functional>
 
void Func1()
{
  std::this_thread::sleep_for(std::chrono::milliseconds(5000));
  std::cout << "Finished Func1"<< std::endl;
}
 
int main()
{
  std::thread t1(Func1);
  t1.join();
 
  std::cout << "Continue Main" << std::endl;
 
  return 0;
}

NOTE: The Continue Main message is only displayed once the function Func1 finishes.

This shows that the main() thread is blocked until the t1 thread completes.

A join blocks the thread that called it; in this example the thread that call the t1 thread is the main() thread.

This may result in the application freezing.


Solution

To not have to wait for a thread to finish, pass the thread to another function which will wait for the thread to finish and execute some action once the execution is done.

#include <iostream>
#include <string>
#include <thread>
#include <functional>
 
void Func1()
{
  std::this_thread::sleep_for(std::chrono::milliseconds(5000));
  std::cout << "Finished Func1"<< std::endl;
}
 
void Func2(std::thread t1)
{
  t1.join();
  std::cout << "Finished Func2" << std::endl;
}
 
int main()
{
  std::thread t1(Func1);
 
  // Pass the responsibility of monitoring the t1 thread to t2.
  std::thread t2(Func2, std::move(t1));
 
  // Do a bunch of other processing without waiting for t1 to finish.
  std::cout << "Continue Main" << std::endl;
 
  // Finally wait for t2 to finish.
  t2.join();
 
  return 0;
}

NOTE: Notice that now the Continue Main message is displayed even before the thread function finishes.

Ownership of the t1 thread is passed to a different thread, in this example, t2, allowing the main() thread to not be blocked.