Namespaces
Variants

std::thread:: thread

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
thread ( ) noexcept ;
(1) (начиная с C++11)
thread ( thread && other ) noexcept ;
(2) (начиная с C++11)
template < class F, class ... Args >
explicit thread ( F && f, Args && ... args ) ;
(3) (начиная с C++11)
thread ( const thread & ) = delete ;
(4) (начиная с C++11)

Создает новый объект std::thread .

1) Создает новый объект std::thread , который не представляет поток выполнения.
2) Конструктор перемещения. Создает объект std::thread для представления потока выполнения, который был представлен объектом other . После этого вызова other больше не представляет поток выполнения.
3) Создает новый объект std::thread и связывает его с потоком выполнения. Новый поток выполнения начинает выполнение:

INVOKE ( decay-copy ( std:: forward < F > ( f ) ) ,
decay-copy ( std:: forward < Args > ( args ) ) ... )

(до C++23)

std:: invoke ( auto ( std:: forward < F > ( f ) ) ,
auto ( std:: forward < Args > ( args ) ) ... )

(начиная с C++23)
Вызовы decay-copy вычисляются (до C++23) Значения, создаваемые с помощью auto подвергаются материализации (начиная с C++23) в текущем потоке, поэтому любые исключения, возникающие во время вычисления и копирования/перемещения аргументов, выбрасываются в текущем потоке, без запуска нового потока.
Эта перегрузка участвует в разрешении перегрузки только если std:: decay < F > :: type (до C++20) std:: remove_cvref_t < F > (начиная с C++20) не является тем же типом, что и std::thread .

Если выполняется любое из следующих условий, программа является некорректной:

(до C++20)

Если любое из следующего является false , программа является некорректной:

(начиная с C++20)
Завершение вызова конструктора синхронизируется с началом вызова копии f в новом потоке выполнения.
4) Конструктор копирования удален; потоки не могут быть копируемыми. Никакие два std::thread объекта не могут представлять один и тот же поток выполнения.

Содержание

Параметры

other - другой объект потока для конструирования данного объекта потока
f - Callable объект для выполнения в новом потоке
args - аргументы для передачи новой функции

Постусловия

1) get_id() равен std:: thread :: id ( ) (т.е. joinable() возвращает false ).
2) other. get_id ( ) равно std::thread::id() и get_id() возвращает значение other. get_id ( ) до начала конструирования.
3) get_id() не равен std::thread::id() (т.е. joinable() возвращает true ).

Исключения

3) std::system_error если поток не может быть запущен. Исключение может представлять код ошибки std::errc::resource_unavailable_try_again или другую реализационно-зависимую ошибку.

Примечания

Аргументы функции потока перемещаются или копируются по значению. Если необходимо передать ссылочный аргумент в функцию потока, его следует обернуть (например, с помощью std::ref или std::cref ).

Любое возвращаемое значение функции игнорируется. Если функция выбрасывает исключение, std::terminate вызывается. Для передачи возвращаемых значений или исключений обратно в вызывающий поток, std::promise или std::async могут быть использованы.

Пример

#include <chrono>
#include <iostream>
#include <thread>
#include <utility>
void f1(int n)
{
    for (int i = 0; i < 5; ++i)
    {
        std::cout << "Thread 1 executing\n";
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
void f2(int& n)
{
    for (int i = 0; i < 5; ++i)
    {
        std::cout << "Thread 2 executing\n";
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
class foo
{
public:
    void bar()
    {
        for (int i = 0; i < 5; ++i)
        {
            std::cout << "Thread 3 executing\n";
            ++n;
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    }
    int n = 0;
};
class baz
{
public:
    void operator()()
    {
        for (int i = 0; i < 5; ++i)
        {
            std::cout << "Thread 4 executing\n";
            ++n;
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    }
    int n = 0;
};
int main()
{
    int n = 0;
    foo f;
    baz b;
    std::thread t1; // t1 не является потоком
    std::thread t2(f1, n + 1); // передача по значению
    std::thread t3(f2, std::ref(n)); // передача по ссылке
    std::thread t4(std::move(t3)); // t4 теперь выполняет f2(). t3 больше не является потоком
    std::thread t5(&foo::bar, &f); // t5 выполняет foo::bar() на объекте f
    std::thread t6(b); // t6 выполняет baz::operator() на копии объекта b
    t2.join();
    t4.join();
    t5.join();
    t6.join();
    std::cout << "Final value of n is " << n << '\n';
    std::cout << "Final value of f.n (foo::n) is " << f.n << '\n';
    std::cout << "Final value of b.n (baz::n) is " << b.n << '\n';
}

Возможный вывод:

Thread 1 executing
Thread 2 executing
Thread 3 executing
Thread 4 executing
Thread 3 executing
Thread 1 executing
Thread 2 executing
Thread 4 executing
Thread 2 executing
Thread 3 executing
Thread 1 executing
Thread 4 executing
Thread 3 executing
Thread 2 executing
Thread 1 executing
Thread 4 executing
Thread 3 executing
Thread 1 executing
Thread 2 executing
Thread 4 executing
Final value of n is 5
Final value of f.n (foo::n) is 5
Final value of b.n (baz::n) is 0

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 2097 C++11 для перегрузки (3) , F мог быть std::thread F ограничен
LWG 3476 C++20 перегрузка (3) напрямую требовала (деградированные типы)
F и типы аргументов должны были быть перемещаемыми
удалены эти
требования [1]
  1. Конструируемость перемещением уже косвенно требуется std::is_constructible_v .

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2024):
  • 33.4.3.3 конструкторы thread [thread.thread.constr]
  • Стандарт C++20 (ISO/IEC 14882:2020):
  • 32.4.2.2 Конструкторы thread [thread.thread.constr]
  • Стандарт C++17 (ISO/IEC 14882:2017):
  • 33.3.2.2 Конструкторы thread [thread.thread.constr]
  • Стандарт C++14 (ISO/IEC 14882:2014):
  • 30.3.1.2 Конструкторы thread [thread.thread.constr]
  • Стандарт C++11 (ISO/IEC 14882:2011):
  • 30.3.1.2 Конструкторы потоков [thread.thread.constr]

Смотрите также

создает новый объект jthread
(публичная функция-член std::jthread )
Документация C для thrd_create