std::jthread::jthread
来自cppreference.com
jthread() noexcept; |
(1) | (C++20 起) |
jthread( jthread&& other ) noexcept; |
(2) | (C++20 起) |
template< class Function, class... Args > explicit jthread( Function&& f, Args&&... args ); |
(3) | (C++20 起) |
jthread( const jthread& ) = delete; |
(4) | (C++20 起) |
构造新 jthread
对象。
1) 构造不表示线程的新
jthread
对象。2) 移动构造函数。构造的
jthread
对象表示之前由 other
表示的执行线程。此调用后 other
不再表示执行线程。3) 创建与执行线程关联的新
jthread
对象。若函数 f 接受 std::stop_token
作为其首参数,则新执行线程开始执行
- std::invoke(std::move(f_copy), get_stop_token(), std::move(args_copy)...) ,若该表达式合法;否则它开始执行
- std::invoke(std::move(f_copy), std::move(args_copy)...) 。
任一情况下,
-
f_copy
为从 std::forward<Function>(f) 构造的 std::decay_t<Function> 类型对象,而 -
args_copy...
为从 std::forward<Args>(args)... 构造的 std::decay_t<Args>... 类型对象。
若 std::remove_cvref_t<Function> 与
jthread
为相同类型则此构造函数不参与重载决议。 构造函数的完成同步于(按 std::memory_order 中定义) f 的副本在新线程上调用的开始。
4) 复制构造函数被删除;线程不可复制。没有二个
std::jthread
对象可表示同一执行线程。参数
other | - | 用以构造此 jthread 对象的另一 jthread 对象
|
f | - | 执行于新线程的可调用 (Callable) 对象 |
args... | - | 传递给函数的参数 |
后条件
1) get_id() 等于 std::jthread::id() (即 joinable() 返回 false )而 get_stop_source().stop_possible() 为 false
2) other.get_id() 等于 std::jthread::id() 而 get_id() 返回构造开始前 other.get_id() 的值
3) get_id() 不等于 std::jthread::id() (即 joinable() 返回 true ),而 get_stop_source().stop_possible() 为 true 。
异常
注解
按值复制或移动给线程函数的参数。若需要传递给线程函数引用参数,则必须包装它(例如用 std::ref 或 std::cref )。
忽略来自函数的任何返回值。若函数抛异常,则调用 std::terminate 。为将返回值或异常传回调用线程,可使用 std::promise 或 std::async 。
示例
运行此代码
#include <iostream> #include <utility> #include <thread> #include <chrono> using namespace std::literals; void f1(int n) { for (int i = 0; i < 5; ++i) { std::cout << "Thread 1 executing\n"; ++n; std::this_thread::sleep_for(10ms); } } void f2(int& n) { for (int i = 0; i < 5; ++i) { std::cout << "Thread 2 executing\n"; ++n; std::this_thread::sleep_for(10ms); } } class foo { public: void bar() { for (int i = 0; i < 5; ++i) { std::cout << "Thread 3 executing\n"; ++n; std::this_thread::sleep_for(10ms); } } 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(10ms); } } int n = 0; }; int main() { int n = 0; foo f; baz b; std::jthread t0; // t0 不是线程 std::jthread t1(f1, n + 1); // 按值传递 std::jthread t2a(f2, std::ref(n)); // 按引用传递 std::jthread t2b(std::move(t2a)); // t2b 现在运行 f2() 。 t2a 不再是线程 std::jthread t3(&foo::bar, &f); // t3 在对象 f 上运行 foo::bar() std::jthread t4(b); // t4 在对象 b 的副本上运行 baz::operator() t1.join(); t2b.join(); t3.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'; // t4 在析构时结合 }
可能的输出:
Thread 2 executing Thread 1 executing Thread 4 executing Thread 3 executing Thread 3 executing Thread 4 executing Thread 2 executing Thread 1 executing Thread 3 executing Thread 1 executing Thread 4 executing Thread 2 executing Thread 3 executing Thread 1 executing Thread 4 executing Thread 2 executing Thread 3 executing Thread 1 executing Thread 4 executing Thread 2 executing Final value of n is 5 Final value of f.n (foo::n) is 5 Final value of b.n (bar::n) is 0
参阅
构造新的 thread 对象 ( std::thread 的公开成员函数) |