Чем отличается функция join()
и detach()
при многопоточности в C++? Соединяет join()
убивает поток?
Что отличается от join() и detach() для многопоточности в C++?
Ответ 1
Объект thread
C++ в целом (но не всегда) представляет собой поток выполнения, который представляет собой концепцию ОС или платформы.
Когда вызывается thread::join()
, вызывающий поток блокируется до тех пор, пока поток выполнения не завершится. В принципе, это один из механизмов, который можно использовать, чтобы знать, когда поток завершен. Когда thread::join()
возвращается, поток выполнения ОС завершен, и объект thread
C++ может быть уничтожен.
thread::detach()
, поток выполнения "отсоединен" от объекта thread
и больше не представлен объектом thread
- это две независимые вещи. Объект thread
C++ может быть уничтожен, а поток выполнения ОС может продолжаться. Если программа должна знать, когда эта последовательность выполнения завершена, необходимо использовать другой механизм. join()
больше нельзя вызывать в этом thread
объекте, поскольку он больше не связан с потоком выполнения.
Считается ошибкой уничтожить объект thread
C++, пока он все еще "соединяется". То есть, чтобы уничтожить объект thread
C++, необходимо либо вызвать join()
либо вызвать detach()
. Если объект thread
C++ все еще соединяется при его уничтожении, будет выбрано исключение.
Некоторые другие способы, по которым объект thread
C++ не будет представлять собой поток выполнения (т.е. Может быть несвязанным):
- Построенный по умолчанию объект
thread
не представляет собой поток выполнения, поэтому он не соединяется. - Поток, который был перемещен из, больше не будет представлять собой поток выполнения, поэтому он не может соединяться.
Ответ 2
join()
не убивает поток. На самом деле он ждет, пока не вернется основная функция потока. Поэтому, если ваша основная функция потока выглядит так:
while (true) {
}
join()
будет ждать вечно.
detatch()
не убивает нити. Фактически он сообщает std::thread
что этот поток должен продолжать работать, даже когда объект std::thread
уничтожен. C++ проверяет в std :: thread destructor, что нить либо соединена, либо отсоединена, и завершает программу, если эта проверка завершилась с ошибкой.
Поэтому, если вы раскомментируете первую строку в main
функции следующего кода, она сработает. Если вы раскомментируете вторую или третью строку, она будет работать нормально.
#include <thread>
void func() {
}
void fail1() {
std::thread t(func);
// will fail when we try to destroy t since it is not joined or detached
}
void works1() {
std::thread t(func);
t.join();
}
void works2() {
std::thread t(func);
t.detach();
}
int main() {
// fail1();
// works1();
// works2();
}