Espacios de nombres
Variantes

std::jthread::jthread

De cppreference.com
 
 
Biblioteca de apoyo de concurrencia
Hilos
(C++11)
(C++20)
Espacio de nombres this_thread
(C++11)
(C++11)
(C++11)
Cancelación cooperativa
Exclusión mutua
(C++11)
Gestión genérica de bloqueo
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Variables de condición
(C++11)
Semáforos
Pestillos y barreras
(C++20)
(C++20)
Futuros
(C++11)
(C++11)
(C++11)
(C++11)
Recuperación segura
(C++26)
Punteros de riesgo
Tipos atómicos
(C++11)
(C++20)
Inicialización de tipos atómicos
(C++11)(en desuso en C++20)
(C++11)(en desuso en C++20)
Orden de memoria
Funciones independientes para operaciones atómicas
Funciones independientes para indicadores atómicos
 
 
<tbody> </tbody>
jthread() noexcept;
(1) (desde C++20)
jthread( jthread&& other ) noexcept;
(2) (desde C++20)
template< class Function, class... Args > explicit jthread( Function&& f, Args&&... args );
(3) (desde C++20)
jthread( const jthread& ) = delete;
(4) (desde C++20)

Construye un nuevo objeto jthread.

1) Crea un nuevo objeto jthread que no representa un hilo.
2) Constructor de movimiento. Construye el objeto jthread para representar el hilo de ejecución que estaba representado por other. Después de esta llamada, other ya no representa un hilo.
3) Crea un nuevo objeto std::jthread y lo asocia con un hilo de ejecución. El nuevo hilo de ejecución comienza a ejecutar
std::invoke(decay_copy(std::forward<Function>(f)),
            get_stop_token(),
            decay_copy(std::forward<Args>(args))...);
si la función f acepta un std::stop_token como su primer argumento; de lo contrario comienza a ejecutar
std::invoke(decay_copy(std::forward<Function>(f)), 
            decay_copy(std::forward<Args>(args))...);

En cualquier caso, decay_copy se define como

template <class T>
std::decay_t<T> decay_copy(T&& v) { return std::forward<T>(v); }
Excepto que las llamadas a decay_copy se evalúan en el contexto del llamante, de modo que cualquier excepción lanzada durante la evaluación y copia/movimiento de los argumentos se lanza en el hilo actual, sin iniciar el nuevo hilo.
La finalización de la invocación del constructor constructor se sincroniza con (como se define en std::memory_order) el inicio de la invocación de la copia de f en el nuevo hilo de ejecución.
Este constructor no participa en la resolución de sobrecarga si std::remove_cvref_t<Function> es el mismo tipo que std::jthread.
4) El constructor de copia está eliminado; los hilos no son copiables. No hay dos objetos std::jthread que puedan representar el mismo hilo de ejecución.

Parámetros

other - Otro objeto jthread con el cual construir este jthread.
f - Objeto invocable (Callable) a ejecutar en el nuevo hilo.
args... - Argumentos a pasar a la nueva función.

Poscondiciones

1) get_id() es igual a std::jthread::id() (es decir, joinable es false) y get_stop_source().stop_possible() es false.
2) other.get_id() es igual a std::jthread::id() y get_id() devuelve el valor de other.get_id() antes del inicio de la construcción.
3) get_id() no es igual a std::jthread::id() (es decir, joinable es true), y get_stop_source().stop_possible() es true.

Excepciones

3) std::system_error si el hilo no se pudo iniciar. 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 de la función del hilo se mueven o se copian por valor. Si es necesario pasar un argumento por referencia a la función del hilo, debe ajustarse (por ejemplo, con std::ref o std::cref).

Se ignora cualquier valor de retorno de la función. Si la función lanza una excepción, se llama a std::terminate. Para pasar valores de retorno o excepciones al hilo llamante, se pueden usar std::promise o std::async.

Ejemplo

#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
using namespace std::literals;

void f1(int n)
{
    for (int i = 0; i < 5; ++i) {
        std::cout << "Hilo 1 ejecutando\n";
        ++n;
        std::this_thread::sleep_for(10ms);
    }
}
 
void f2(int& n)
{
    for (int i = 0; i < 5; ++i) {
        std::cout << "Hilo 2 ejecutando\n";
        ++n;
        std::this_thread::sleep_for(10ms);
    }
}
 
class foo
{
public:
    void bar()
    {
        for (int i = 0; i < 5; ++i) {
            std::cout << "Hilo 3 ejecutando\n";
            ++n;
            std::this_thread::sleep_for(10ms);
        }
    }
    int n = 0;
};

class baz
{
public:
    void operator()()
    {
        for (int i = 0; i < 5; ++i) {
            std::cout << "Hilo 4 ejecutando\n";
            ++n;
            std::this_thread::sleep_for(10ms);
        }
    }
    int n = 0;
};
 
int main()
{
    int n = 0;
    foo f;
    baz b;
    std::jthread t0; // t0 no es un hilo
    std::jthread t1(f1, n + 1); // pasar por valor
    std::jthread t2a(f2, std::ref(n)); // pasar por referencia
    std::jthread t2b(std::move(t2a)); // t2b ahora ejecuta f2(). t2a ya no es un hilo
    std::jthread t3(&foo::bar, &f); // t3 ejecuta foo::bar() en el objeto f
    std::jthread t4(b); // t4 ejecuta baz::operator() en una copia del objeto b
    t1.join();
    t2b.join();
    t3.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';
    // t4 se une durante la destrucción
}

Posible salida:

Hilo 2 ejecutando
Hilo 1 ejecutando
Hilo 4 ejecutando
Hilo 3 ejecutando
Hilo 3 ejecutando
Hilo 4 ejecutando
Hilo 2 ejecutando
Hilo 1 ejecutando
Hilo 3 ejecutando
Hilo 1 ejecutando
Hilo 4 ejecutando
Hilo 2 ejecutando
Hilo 3 ejecutando
Hilo 1 ejecutando
Hilo 4 ejecutando
Hilo 2 ejecutando
Hilo 3 ejecutando
Hilo 1 ejecutando
Hilo 4 ejecutando
Hilo 2 ejecutando
Valor final de n es 5
Valor final de f.n (foo::n) es 5
Valor final de b.n (bar::n) es 0

Véase también

Construye un nuevo objeto hilo
(función miembro pública de std::thread) [editar]
Documentación de C para thrd_create