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 在对象 f 上运行 foo::bar()
    std::thread t6(b); // t6 在对象 b 的副本上运行 baz::operator()
    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++标准。

缺陷报告 应用于 发布时的行为 正确行为
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.constr]
  • C++20 标准 (ISO/IEC 14882:2020):
  • 32.4.2.2 线程构造函数 [thread.thread.constr]
  • C++17 标准 (ISO/IEC 14882:2017):
  • 33.3.2.2 线程构造函数 [thread.thread.constr]
  • C++14 标准 (ISO/IEC 14882:2014):
  • 30.3.1.2 线程构造函数 [thread.thread.constr]
  • C++11 标准 (ISO/IEC 14882:2011):
  • 30.3.1.2 线程构造函数 [thread.thread.constr]

参见

构造新的 jthread 对象
( std::jthread 的公开成员函数)
C 文档 关于 thrd_create