Files
ubbook/concurrency/jthread.md
T
2022-02-20 14:42:44 +02:00

35 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Threads joining
А вы уже заметили, что в [предыдущих](./race_condition.md) заметках я использую `std::jthread` из C++20 вместо `std::thread`? И зачем?
А все очень просто: деструктор `std::thread` дурной.
Везде, где может начать вызываться деструктор `std::thread`, нужно втыкать
```C++
// std::thread t1;
if (t1.joinable()) { // Если вы не уверены в богатой жизненной истории
// объекта t1, обязательно выполняйте эту проверку
t1.join(); // или t1.detach()
}
```
Чтобы ознаменовать свое желание (или нежелание) дожидаться окончания выполнения потока.
Иначе деструктор потока повалит вашу программу, вызвав `std::terminate`.
Очень удобно и очень по RAII-шному, неправда ли?
Нет, конечно, совсем везде втыкать не надо. Если вы знаете, что кто-то другой уже выполнил это заклинание, или содержимое объекта `std::thread` переместили в другой объект (`t2 = std::move(t1)`).
И тем более не надо просто так втыкать этот код, обращающийся к одному и тому же объекту `std::thread` из разных потоков. Иначе — race condition. Надо синхронизировать.
И, конечно же, убедитесь что этот код ни в коем случае не будет выполняться параллельно с вызовом деструктора `t1`; Деструктор тоже вызывает `joinable`, а это опять race condition.
Собираетесь сделать обертку над `std::thread`, чтобы вызывать `join` в ее деструкторе? Спешу порадовать: `join`/`detach` кидают исключения. Со всеми вытекающими [проблемами](../runtime/noexcept.md).
Здорово, да? Поэтому в примерах был и будет `std::jthread`. Его деструктор сам выполняет `join` и снимает хотя бы часть головной боли.
А если вас `join` не устраивает, не хотите ждать и пользуетесь `detach`... Ну что ж. Право ваше. Только помните, что все потоки резко и внезапно помрут, когда закончится `main`.
## Полезные ссылки
1. https://en.cppreference.com/w/cpp/thread/thread
2. https://en.cppreference.com/w/cpp/thread/jthread