Чем отличается функция 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();
}