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);
}