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

Construit un nouvel objet std::thread .

1) Crée un nouvel objet std::thread qui ne représente pas un thread.
2) Constructeur de déplacement. Construit l'objet std::thread pour représenter le thread d'exécution qui était représenté par other . Après cet appel, other ne représente plus un thread d'exécution.
3) Crée un nouvel objet std::thread et l'associe à un thread d'exécution. Le nouveau thread d'exécution commence à exécuter :

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

(jusqu'en C++23)

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

(depuis C++23)
Les appels de decay-copy sont évalués (jusqu'en C++23) Les valeurs produites par auto sont matérialisées (depuis C++23) dans le thread actuel, de sorte que toute exception levée durant l'évaluation et la copie/déplacement des arguments est levée dans le thread actuel, sans démarrer le nouveau thread.
Cette surcharge participe à la résolution de surcharge uniquement si std:: decay < F > :: type (jusqu'en C++20) std:: remove_cvref_t < F > (depuis C++20) n'est pas du même type que std::thread .

Si l'une des conditions suivantes est satisfaite, le programme est mal formé :

(jusqu'en C++20)

Si l'une des conditions suivantes est false , le programme est mal formé :

(depuis C++20)
L'achèvement de l'invocation du constructeur se synchronise avec le début de l'invocation de la copie de f sur le nouveau thread d'exécution.
4) Le constructeur de copie est supprimé ; les threads ne sont pas copiables. Aucun deux std::thread objets ne peuvent représenter le même thread d'exécution.

Table des matières

Paramètres

other - autre objet thread pour construire cet objet thread
f - Callable objet à exécuter dans le nouveau thread
args - arguments à passer à la nouvelle fonction

Postconditions

1) get_id() égal à std:: thread :: id ( ) (c'est-à-dire que joinable() est false ).
2) other. get_id ( ) égal à std::thread::id() et get_id() retourne la valeur de other. get_id ( ) avant le début de la construction.
3) get_id() différent de std::thread::id() (c'est-à-dire que joinable() est true ).

Exceptions

3) std::system_error si le thread n'a pas pu être démarré. L'exception peut représenter la condition d'erreur std::errc::resource_unavailable_try_again ou une autre condition d'erreur spécifique à l'implémentation.

Notes

Les arguments de la fonction de thread sont déplacés ou copiés par valeur. Si un argument de référence doit être passé à la fonction de thread, il doit être encapsulé (par exemple, avec std::ref ou std::cref ).

Toute valeur de retour de la fonction est ignorée. Si la fonction lance une exception, std::terminate est appelé. Afin de transmettre les valeurs de retour ou les exceptions au thread appelant, std::promise ou std::async peuvent être utilisés.

Exemple

#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 n'est pas un thread
    std::thread t2(f1, n + 1); // passage par valeur
    std::thread t3(f2, std::ref(n)); // passage par référence
    std::thread t4(std::move(t3)); // t4 exécute maintenant f2(). t3 n'est plus un thread
    std::thread t5(&foo::bar, &f); // t5 exécute foo::bar() sur l'objet f
    std::thread t6(b); // t6 exécute baz::operator() sur une copie de l'objet b
    t2.join();
    t4.join();
    t5.join();
    t6.join();
    std::cout << "Valeur finale de n est " << n << '\n';
    std::cout << "Valeur finale de f.n (foo::n) est " << f.n << '\n';
    std::cout << "Valeur finale de b.n (baz::n) est " << b.n << '\n';
}

Sortie possible :

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

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Applicable à Comportement publié Comportement corrigé
LWG 2097 C++11 pour la surcharge (3) , F pouvait être std::thread F est contraint
LWG 3476 C++20 la surcharge (3) exigeait directement que (les types dégradés de)
F et les types d'arguments soient move constructible
ces exigences ont été
supprimées [1]
  1. La constructibilité par déplacement est déjà indirectement requise par std::is_constructible_v .

Références

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

Voir aussi

construit un nouvel objet jthread
(fonction membre publique de std::jthread )
Documentation C pour thrd_create