命名空间
变体
操作

std::thread::thread

来自 cppreference.cn
< cpp‎ | thread‎ | thread
 
 
并发支持库
线程
(C++11)
(C++20)
this_thread 命名空间
(C++11)
(C++11)
(C++11)
协同取消
互斥
(C++11)
通用锁管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
条件变量
(C++11)
信号量
门闩和屏障
(C++20)
(C++20)
期值
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
危险指针
原子类型
(C++11)
(C++20)
原子类型的初始化
(C++11)(C++20 中已弃用)
(C++11)(C++20 中已弃用)
内存排序
(C++11)(C++26 中已弃用)
原子操作的自由函数
原子标志的自由函数
 
 
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 起)
构造函数的调用完成 同步于 (synchronizes with) 新线程上 f 的副本的调用开始。
4) 复制构造函数被删除;线程不可复制。任何两个 std::thread 对象都不能表示相同的执行线程。

目录

[编辑] 参数

其他 - 另一个线程对象,用于构造此线程对象
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::refstd::cref)。

函数的所有返回值都将被忽略。如果函数抛出异常,则调用 std::terminate。为了将返回值或异常传回调用线程,可以使用 std::promisestd::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 is not a thread
    std::thread t2(f1, n + 1); // pass by value
    std::thread t3(f2, std::ref(n)); // pass by reference
    std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
    std::thread t5(&foo::bar, &f); // t5 runs foo::bar() on object f
    std::thread t6(b); // t6 runs baz::operator() on a copy of object b
    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
English Deutsch 日本語 한국어 中文(简体) 中文(繁體)