Что отличается от join() и detach() для многопоточности в C++?

Чем отличается функция join() и detach() при многопоточности в C++? Соединяет join() убивает поток?

Ответы

Ответ 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();
}