std::thread::thread

来自cppreference.com
< 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++20)
(C++20)
未来体
(C++11)
(C++11)
(C++11)
安全回收
风险指针
原子类型
(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) 移动构造函数。构造表示 other 曾表示的执行线程的 std::thread 对象。此调用后 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 不可复制。两个 std::thread 对象不能表示同一执行线程。

参数

other-用来构造此线程对象的另一线程对象
f-在新线程执行的可调用 (Callable) 对象
args-传递给新函数的实参

后条件

1)get_id() 等于 std::thread::id()(即 joinablefalse)。
2)other.get_id() 等于 std::thread::id()get_id() 返回构造开始前 other.get_id() 的值。
3)get_id() 不等于 std::thread::id()(即 joinabletrue)。

异常

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 << "正在执行线程1\n";
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
 
void f2(int& n)
{
    for (int i = 0; i < 5; ++i)
    {
        std::cout << "正在执行线程2\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 << "正在执行线程3\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 << "正在执行线程4\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 << "n 的最终值是 " << n << '\n';
    std::cout << "f.n (foo::n) 的最终值是 " << f.n << '\n';
    std::cout << "b.n (baz::n) 的最终值是 " << b.n << '\n';
}

可能的输出:

正在执行线程1
正在执行线程2
正在执行线程3
正在执行线程4
正在执行线程3
正在执行线程1
正在执行线程2
正在执行线程4
正在执行线程2
正在执行线程3
正在执行线程1
正在执行线程4
正在执行线程3
正在执行线程2
正在执行线程1
正在执行线程4
正在执行线程3
正在执行线程1
正在执行线程2
正在执行线程4
n 的最终值是 5
f.n (foo::n) 的最终值是 5
b.n (baz::n) 的最终值是 0

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告应用于出版时的行为正确行为
LWG 2097C++11对于重载 (3)F 可以是 std::threadF 进行约束
LWG 3476C++20重载 (3) 直接要求 F 和实参类型(在退化后)必须可移动构造移除这些要求[1]
  1. std::is_constructible_v 已间接要求了可移动构造性。

引用

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

参阅

创建新的 jthread 对象
(std::jthread 的公开成员函数)
thrd_create 的 C 文档