Namespaces
Variants

std::thread:: thread

From es.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) (desde C++11)
thread ( thread && other ) noexcept ;
(2) (desde C++11)
template < class F, class ... Args >
explicit thread ( F && f, Args && ... args ) ;
(3) (desde C++11)
thread ( const thread & ) = delete ;
(4) (desde C++11)

Construye un nuevo std::thread objeto.

1) Crea un nuevo objeto std::thread que no representa un hilo.
2) Constructor de movimiento. Construye el objeto std::thread para representar el hilo de ejecución que estaba representado por other . Después de esta llamada, other ya no representa un hilo de ejecución.
3) Crea un nuevo objeto std::thread y lo asocia con un hilo de ejecución. El nuevo hilo de ejecución comienza ejecutando:

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

(hasta C++23)

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

(desde C++23)
Las llamadas de decay-copy son evaluadas (until C++23) Los valores producidos por auto son materializados (since C++23) en el hilo actual, de modo que cualquier excepción lanzada durante la evaluación y copia/movimiento de los argumentos es lanzada en el hilo actual, sin iniciar el nuevo hilo.
Esta sobrecarga participa en la resolución de sobrecarga solo si std:: decay < F > :: type (hasta C++20) std:: remove_cvref_t < F > (desde C++20) no es del mismo tipo que std::thread .

Si se satisface alguna de las siguientes condiciones, el programa está mal formado:

(hasta C++20)

Si alguna de las siguientes es false , el programa está mal formado:

(desde C++20)
La finalización de la invocación del constructor se sincroniza con el comienzo de la invocación de la copia de f en el nuevo hilo de ejecución.
4) El constructor de copia está eliminado; los hilos no son copiables. No hay dos std::thread objetos que puedan representar el mismo hilo de ejecución.

Contenidos

Parámetros

other - otro objeto thread con el cual construir este objeto thread
f - Callable objeto a ejecutar en el nuevo thread
args - argumentos para pasar a la nueva función

Postcondiciones

1) get_id() igual a std:: thread :: id ( ) (es decir, joinable() es false ).
2) other. get_id ( ) igual a std::thread::id() y get_id() devuelve el valor de other. get_id ( ) previo al inicio de la construcción.
3) get_id() no es igual a std::thread::id() (es decir, joinable() es true ).

Excepciones

3) std::system_error si el hilo no pudo iniciarse. La excepción puede representar la condición de error std::errc::resource_unavailable_try_again u otra condición de error específica de la implementación.

Notas

Los argumentos para la función del hilo se mueven o copian por valor. Si es necesario pasar un argumento de referencia a la función del hilo, debe envolverse (por ejemplo, con std::ref o std::cref ).

Cualquier valor de retorno de la función es ignorado. Si la función lanza una excepción, std::terminate es llamado. Para pasar valores de retorno o excepciones de vuelta al hilo llamador, std::promise o std::async pueden ser utilizados.

Ejemplo

#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 no es un thread
    std::thread t2(f1, n + 1); // pasar por valor
    std::thread t3(f2, std::ref(n)); // pasar por referencia
    std::thread t4(std::move(t3)); // t4 ahora ejecuta f2(). t3 ya no es un thread
    std::thread t5(&foo::bar, &f); // t5 ejecuta foo::bar() en el objeto f
    std::thread t6(b); // t6 ejecuta baz::operator() en una copia del objeto b
    t2.join();
    t4.join();
    t5.join();
    t6.join();
    std::cout << "Valor final de n es " << n << '\n';
    std::cout << "Valor final de f.n (foo::n) es " << f.n << '\n';
    std::cout << "Valor final de b.n (baz::n) es " << b.n << '\n';
}

Salida posible:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2097 C++11 para la sobrecarga (3) , F podría ser std::thread F está restringido
LWG 3476 C++20 la sobrecarga (3) requería directamente que (los tipos decaídos de)
F y los tipos de argumento fueran construibles por movimiento
se eliminaron estos
requisitos [1]
  1. ↑ La capacidad de construcción por movimiento ya está indirectamente requerida por std::is_constructible_v .

Referencias

  • Estándar C++23 (ISO/IEC 14882:2024):
  • 33.4.3.3 constructores de thread [thread.thread.constr]
  • Estándar C++20 (ISO/IEC 14882:2020):
  • 32.4.2.2 constructores de thread [thread.thread.constr]
  • Estándar C++17 (ISO/IEC 14882:2017):
  • 33.3.2.2 constructores de thread [thread.thread.constr]
  • Estándar C++14 (ISO/IEC 14882:2014):
  • 30.3.1.2 constructores de thread [thread.thread.constr]
  • Estándar C++11 (ISO/IEC 14882:2011):
  • 30.3.1.2 constructores de thread [thread.thread.constr]

Véase también

construye un nuevo objeto jthread
(función miembro pública de std::jthread )
Documentación C para thrd_create