C++20: std::jthread

auto join() in destructor

In C++20 there is new thread type std::jthread, which means joined thread. Previous std::thread if destructor will be called without join() function, in this case will be called std::terminate(). But in std::jthread in destructor is called join() function.

std::jthread object is located in <thread> header.

void _internal_thread()
{

}

int main()
{
	std::jthread _thread{ _internal_thread };
	// no exception here
}

std::stop_token

Also in std::jthread there is possibility to stop thread when it’s needed. Thread function can have parameter std::stop_token which can be checked in while loop inside thread.

For example:

#include <iostream>
#include <thread>

using namespace std::chrono_literals;

void _internal_thread(std::stop_token stop)
{
	while (!stop.stop_requested())
	{
		std::cout << "work..." << std::endl;
		std::this_thread::sleep_for(0.5s);
	}
}

int main()
{
	std::jthread _thread{ _internal_thread };
	std::this_thread::sleep_for(2s);
}

In case when we need to pass additional parameters to thread function, std::stop_token need to be first parameter.

void _internal_thread(std::stop_token stop, int x) // ok
{
	while (!stop.stop_requested())
	{
		std::cout << "work..." << std::endl;
		std::this_thread::sleep_for(0.5s);
	}
}

// error
void _internal_thread(int x, std::stop_token stop)
{
	while (!stop.stop_requested())
	{
		std::cout << "work..." << std::endl;
		std::this_thread::sleep_for(0.5s);
	}
}

If needed we can get std::stop_source and call request_stop() when it needed.

std::jthread _thread{ _internal_thread, 10 };

bool result = _thread.get_stop_source().request_stop();

std::stop_callback

Also there is new std::stop_callback object, which can execute in case when request_stop() is called.

For example:

#include <iostream>
#include <thread>

using namespace std::chrono_literals;

void _internal_thread(std::stop_token stop, int x)
{
	while (!stop.stop_requested())
	{
		std::cout << "work..." << std::endl;
		std::this_thread::sleep_for(0.5s);
	}
}

int main()
{
  std::jthread _thread{ _internal_thread, 10 };

  std::stop_callback 
  _stop{_thread.get_stop_token(), []() {
     std::cout << "show stop" << std::endl;
  }};

  _thread.get_stop_source().request_stop();

  std::this_thread::sleep_for(2s);
}