Использование join и detach c++
Имеется следующий код:
class MyClass {
public:
void doWork() {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "ID потока: " << std::this_thread::get_id() << "\tdoWork started\t" << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "ID потока: " << std::this_thread::get_id() << "\tdoWork stopped\t" << "\n";
};
void doWork2(int a) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "ID потока: " << std::this_thread::get_id() << "\tdoWork2 started\t" << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "Значение параметра doWork2 " << a;
std::cout << "ID потока: " << std::this_thread::get_id() << "\tdoWork2 stopped\t" << "\n";
};
int sum(int a, int b) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "ID потока: " << std::this_thread::get_id() << "\tsum started\t" << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "ID потока: " << std::this_thread::get_id() << "\tsum stopped\t" << "\n";
return a + b;
}
};
int main() {
setlocale(LC_ALL, "ru");
MyClass class1;
std::thread th1(&MyClass::doWork, class1);
for (int i = 0; i < 3; ++i) {
std::cout << "ID потока: " << std::this_thread::get_id() << "\tmain work\t" << i << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
};
th1.join();
return 0;
}
Я ведь правильно понимаю, что join нужен для того, чтобы если main завершился раньше, программа дождалась выполнения созданного th1 потока?
Также не очень понимаю случаи, когда нужен detach.
detach же просто "отправит поток в свободное плавание", как тогда забрать из него результат и в каких кейсах применять его вместо join?
Спасибо
Ответы (1 шт):
После запуска потока экземпляр std::thread
становится владельцем запущенного потока. Блокирующий вызов join
дожидается завершения потока и освобождает ассоциированные ресурсы, обеспечивая возможность корректно завершить жизнь ранее созданных объектов, на которые мог ссылаться код в завершенном потоке. Этот вызов является обязательным. Вызов деструктора экземпляра std::thread
, который еще является владельцем запущенного потока приводит к аварийному завершению программы.
Вызовы detach
в грамотном коде не нужны и обычно являются грубой ошибкой. Единственная ситуация, когда их использование можно как-то оправдать - вызов в потоке сторонней функции, блокирующей его на неопределенное время. Тогда вызов detach
можно использовать как менее убогую альтернативу преднамерреной утечке ресурсов при создании потока посредством new
без соответствующего вызова delete
.
В С++20 появлися класс std::jthread
, который имеет встроенный механизм оповещения о необходимости завершения потока и сам вызывает join
в деструкторе.