mirror of
https://github.com/Nekrolm/ubbook.git
synced 2026-06-09 13:14:18 +03:00
35 lines
2.9 KiB
Markdown
35 lines
2.9 KiB
Markdown
# 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 |