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

Konstruiert ein neues std::thread Objekt.

1) Erstellt ein neues std::thread Objekt, das keinen Thread repräsentiert.
2) Move-Konstruktor. Konstruiert das std::thread Objekt, um den Ausführungs-Thread darzustellen, der zuvor durch other repräsentiert wurde. Nach diesem Aufruf repräsentiert other keinen Ausführungs-Thread mehr.
3) Erstellt ein neues std::thread -Objekt und verknüpft es mit einem Ausführungsthread. Der neue Ausführungsthread beginnt mit der Ausführung von:

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

(bis C++23)

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

(seit C++23)
Die Aufrufe von decay-copy werden ausgewertet (bis C++23) Die durch auto erzeugten Werte werden materialisiert (seit C++23) im aktuellen Thread, sodass alle während der Auswertung und des Kopierens/Verschiebens der Argumente ausgelösten Ausnahmen im aktuellen Thread geworfen werden, ohne einen neuen Thread zu starten.
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn std:: decay < F > :: type (bis C++20) std:: remove_cvref_t < F > (seit C++20) nicht denselben Typ wie std::thread hat.

Wenn eine der folgenden Bedingungen erfüllt ist, ist das Programm fehlerhaft:

(bis C++20)

Wenn eines der folgenden false ist, ist das Programm fehlerhaft:

(seit C++20)
Der Abschluss des Aufrufs des Konstruktors synchronisiert mit dem Beginn des Aufrufs der Kopie von f im neuen Ausführungsstrang.
4) Der Kopierkonstruktor ist gelöscht; Threads sind nicht kopierbar. Keine zwei std::thread -Objekte dürfen denselben Ausführungsstrang repräsentieren.

Inhaltsverzeichnis

Parameter

other - ein anderes Thread-Objekt, mit dem dieses Thread-Objekt konstruiert werden soll
f - Callable Objekt, das im neuen Thread ausgeführt werden soll
args - Argumente, die an die neue Funktion übergeben werden sollen

Nachbedingungen

1) get_id() entspricht std:: thread :: id ( ) (d.h. joinable() ist false ).
2) other. get_id ( ) gleich std::thread::id() und get_id() gibt den Wert von other. get_id ( ) vor Beginn der Konstruktion zurück.
3) get_id() ungleich std::thread::id() (d.h. joinable() ist true ).

Ausnahmen

3) std::system_error falls der Thread nicht gestartet werden konnte. Die Exception kann den Fehlerzustand std::errc::resource_unavailable_try_again oder einen anderen implementationsspezifischen Fehlerzustand repräsentieren.

Hinweise

Die Argumente der Thread-Funktion werden durch Verschieben oder Kopieren übergeben. Wenn ein Referenzargument an die Thread-Funktion übergeben werden muss, muss es umschlossen werden (z.B. mit std::ref oder std::cref ).

Jeder Rückgabewert der Funktion wird ignoriert. Wenn die Funktion eine Exception wirft, std::terminate wird aufgerufen. Um Rückgabewerte oder Exceptions an den aufrufenden Thread zurückzugeben, std::promise oder std::async können verwendet werden.

Beispiel

#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 ist kein Thread
    std::thread t2(f1, n + 1); // call by value
    std::thread t3(f2, std::ref(n)); // call by reference
    std::thread t4(std::move(t3)); // t4 führt nun f2() aus. t3 ist kein Thread mehr
    std::thread t5(&foo::bar, &f); // t5 führt foo::bar() auf Objekt f aus
    std::thread t6(b); // t6 führt baz::operator() auf einer Kopie von Objekt b aus
    t2.join();
    t4.join();
    t5.join();
    t6.join();
    std::cout << "Endwert von n ist " << n << '\n';
    std::cout << "Endwert von f.n (foo::n) ist " << f.n << '\n';
    std::cout << "Endwert von b.n (baz::n) ist " << b.n << '\n';
}

Mögliche Ausgabe:

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

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 2097 C++11 für Überladung (3) , F könnte std::thread sein F ist eingeschränkt
LWG 3476 C++20 Überladung (3) erforderte direkt, dass (die zerfallenen Typen von)
F und die Argumenttypen move-konstruierbar sind
entfernte diese
Anforderungen [1]
  1. Die Move-Konstruierbarkeit ist bereits indirekt durch std::is_constructible_v vorausgesetzt.

Referenzen

  • C++23-Standard (ISO/IEC 14882:2024):
  • 33.4.3.3 Thread-Konstruktoren [thread.thread.constr]
  • C++20-Standard (ISO/IEC 14882:2020):
  • 32.4.2.2 Thread-Konstruktoren [thread.thread.constr]
  • C++17-Standard (ISO/IEC 14882:2017):
  • 33.3.2.2 Thread-Konstruktoren [thread.thread.constr]
  • C++14-Standard (ISO/IEC 14882:2014):
  • 30.3.1.2 Thread-Konstruktoren [thread.thread.constr]
  • C++11-Standard (ISO/IEC 14882:2011):
  • 30.3.1.2 Thread-Konstruktoren [thread.thread.constr]

Siehe auch

konstruiert neues jthread Objekt
(öffentliche Elementfunktion von std::jthread )
C-Dokumentation für thrd_create