std::jthread:: jthread
|
jthread
(
)
noexcept
;
|
(1) | (C++20 起) |
|
jthread
(
jthread
&&
other
)
noexcept
;
|
(2) | (C++20 起) |
|
template
<
class
F,
class
...
Args
>
explicit jthread ( F && f, Args && ... args ) ; |
(3) | (C++20 起) |
|
jthread
(
const
jthread
&
)
=
delete
;
|
(4) | (C++20 起) |
构造新的
std::jthread
对象。
std::jthread
对象,该对象不表示任何线程。
std::jthread
对象以表示原本由
other
表示的执行线程。此调用后
other
不再代表任何执行线程。
std::jthread
对象并将其与执行线程关联。
新的执行线程开始执行:
std::
invoke
(
decay-copy
(
std::
forward
<
F
>
(
f
)
)
, get_stop_token
(
)
,
decay-copy
(
std::
forward
<
Args
>
(
args
)
)
...
)
|
(C++23 前) |
|
std::
invoke
(
auto
(
std::
forward
<
F
>
(
f
)
)
, get_stop_token
(
)
,
|
(C++23 起) |
若上述表达式合法,否则开始执行:
std::
invoke
(
decay-copy
(
std::
forward
<
F
>
(
f
)
)
,
decay-copy
(
std::
forward
<
Args
>
(
args
)
)
...
)
。
|
(C++23 前) |
|
std::
invoke
(
auto
(
std::
forward
<
F
>
(
f
)
)
,
|
(C++23 起) |
- std:: is_constructible_v < std:: decay_t < F > , F >
- ( std:: is_constructible_v < std:: decay_t < Args > , Args > && ... )
-
std::
is_invocable_v
<
std::
decay_t
<
F
>
,
std::
decay_t
<
Args
>
...
>
||
std:: is_invocable_v < std:: decay_t < F > , std:: stop_token , std:: decay_t < Args > ... >
std::jthread
对象都不能表示同一执行线程。
目录 |
参数
| other | - |
用于构造此
std::jthread
对象的另一个
std::jthread
对象
|
| f | - | 在新线程中执行的 Callable 对象 |
| args | - | 传递给新函数的参数 |
后置条件
get_id()
等于
std::jthread::id()
(即
joinable()
返回
false
)且
get_stop_source
(
)
.
stop_possible
(
)
为
false
。
get_id()
不等于
std::jthread::id()
(即
joinable()
返回
true
),且
get_stop_source
(
)
.
stop_possible
(
)
为
true
。
异常
注释
传递给线程函数的参数会通过值进行移动或复制。如果需要将引用参数传递给线程函数,必须将其包装(例如使用 std::ref 或 std::cref )。
函数的任何返回值均被忽略。若函数抛出异常,将调用 std::terminate 。要将返回值或异常传递回调用线程,可使用 std::promise 或 std::async 。
示例
#include <chrono> #include <iostream> #include <thread> #include <utility> 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 (baz::n) is 0
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| DR | 适用范围 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 3476 | C++20 |
重载
(3)
直接要求(退化后的类型)
F
和参数类型可移动构造
|
移除这些
要求 [1] |
- ↑ 移动构造特性已通过 std::is_constructible_v 间接要求。
参见
构造新的
thread
对象
(
std::thread
的公开成员函数)
|
|
|
C 文档
用于
thrd_create
|
|