Daily bit(e) C++. std::jthread
Daily bit(e) C++ #8, новый стандартный поток: std::jthread
.
В C++20 мы получили новую версию стандартного потока в виде std::jthread
(joining thread).
При использовании std::thread
удерживаемый поток должен быть присоединен или отсоединен до того, как переменная будет уничтожена (иначе программа завершится).
std::jthread
решает эту проблему, автоматически присоединяясь в деструкторе, устраняя необходимость в обертках.
#include <chrono>
#include <thread>
#include <iostream>
#include <syncstream>
int main()
{
{
// Создаем поток:
auto t = std::thread([]{
std::osyncstream(std::cerr) << "Start of thread "
<< std::this_thread::get_id() << "\n";
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
std::osyncstream(std::cerr) << "End of thread "
<< std::this_thread::get_id() << "\n";
});
std::osyncstream(std::cerr) << "Done spawning thread.\n";
// Требуется join, будет блокировать, пока не закончится сон 1 сек
t.join();
std::osyncstream(std::cerr) << "Scope end.\n";
} // конец области видимости, t разрушается
std::osyncstream(std::cerr) << "\n";
{
// Создаем поток:
auto t = std::jthread([]{
std::osyncstream(std::cerr) << "Start of thread "
<< std::this_thread::get_id() << "\n";
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
std::osyncstream(std::cerr) << "End of thread "
<< std::this_thread::get_id() << "\n";
});
std::osyncstream(std::cerr) << "Scope end.\n";
} // конец области видимости, t разрушается,
// а поток присоединен как часть этого
std::osyncstream(std::cerr) << "\n";
// Запускаем поток и сразу же присоединяем его,
// т.к. временное возвращаемое значение будет уничтожено.
std::jthread([]{});
// Запускаем поток и (очень вероятно) немедленно завершаемся,
// т.к. временное возвращаемое значение будет уничтожено.
std::thread([]{});
}
Открыть пример на Compiler Explorer.
Вывод программы:
Done spawning thread.
Start of thread 139962836096768
End of thread 139962836096768
Scope end.
Scope end.
Start of thread 139962836096768
End of thread 139962836096768
terminate called without an active exception
Program terminated with signal: SIGSEGV