std::thread::thread
来自cppreference.com
thread() noexcept; |
(1) | (C++11 起) |
thread( thread&& other ) noexcept; |
(2) | (C++11 起) |
template< class Function, class... Args > explicit thread( Function&& f, Args&&... args ); |
(3) | (C++11 起) |
thread( const thread& ) = delete; |
(4) | (C++11 起) |
构造新的 thread
对象。
1) 构造不表示线程的新
thread
对象。2) 移动构造函数。构造表示曾为
other
所表示的执行线程的 thread
对象。此调用后 other
不再表示执行线程。3) 构造新的
std::thread
对象并将它与执行线程关联。新的执行线程开始执行 /*INVOKE*/(std::move(f_copy), std::move(args_copy)...) ,其中
- /*INVOKE*/ 进行可调用 (Callable) 中指定的
INVOKE
操作,这能由 std::invoke 进行 (C++17 起),而 -
f_copy
是类型为 std::decay<Function>::type 并从 std::forward<Function>(f) 构造的对象,而 -
args_copy...
是类型为 std::decay<Args>::type... 并从 std::forward<Args>(args)... 构造的对象。
INVOKE
操作非法则程序非良构。 若 std::decay<Function>::type 与
thread
为同一类型,则此构造函数不参与重载决议。 构造函数的调用完成同步于(定义于 std::memory_order )新的执行线程上 f 副本的调用开始。
4) 复制构造函数被删除;
thread
不可复制。没有二个 std::thread
对象可表示同一执行线程。参数
other | - | 用以构造此 thread 的另一 thread 对象 |
f | - | 执行于新线程的可调用 (Callable) |
args... | - | 传递给新函数的参数 |
后条件
异常
注解
移动或按值复制线程函数的参数。若需要传递引用参数给线程函数,则必须包装它(例如用 std::ref 或 std::cref )。
忽略来自函数的任何返回值。若函数抛异常,则调用 std::terminate 。为将返回值或异常传递回调用方线程,可使用 std::promise 或 std::async 。
示例
运行此代码
#include <iostream> #include <utility> #include <thread> #include <chrono> 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 | 接收一个可调用 (Callable) 对象的构造函数可能与移动构造函数有歧义 | 已约束 |
引用
- 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 的公开成员函数) |