Каким вызовом в стандартном C++ создаётся новый поток?

«Каким вызовом в стандартном C++ создаётся новый поток?» — вопрос из категории Многопоточность, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В современном C++ (начиная с C++11) для создания потока используется конструктор класса std::thread из заголовочного файла <thread>.

Базовый синтаксис:

#include <thread>

std::thread thread_object(callable, arg1, arg2, ...);

Где callable — это функция, функциональный объект (лямбда, объект с operator()) или указатель на функцию-член класса. Поток начинает выполнение немедленно после создания.

Примеры:

  1. С обычной функцией:
    void print_message(const std::string& msg) {
        std::cout << msg << 'n';
    }
    int main() {
        std::thread t(print_message, "Hello from thread!");
        t.join(); // Важно: дождаться завершения перед выходом из main
        return 0;
    }
  2. С лямбда-выражением:
    std::thread t([]() {
        std::cout << "Lambda in threadn";
    });

Критически важные моменты:

  • Необходимо явно управлять жизненным циклом потока: вызвать либо join() (ожидание завершения), либо detach() (разрешить самостоятельное завершение). Если этого не сделать, деструктор std::thread вызовет std::terminate и аварийно завершит программу.
  • Для передачи аргументов по ссылке нужно использовать std::ref() или std::cref().
  • Потоки нельзя копировать, но можно перемещать (std::move).