想象我创建一个像这样的线程:
std::jthread( []( string &&str ) {}, move( str ) );
如果线程创建失败怎么办?字符串是否保证保留其旧内容?
实际上,
std::thread
调用的参数存储在类似于std::tuple
按值的形式中。这必须在创建 std::thread
的上下文中完成。然后在线程中以类似于std::apply
的方式调用函数对象。
不会指定何时发生创建实际线程原语失败的情况。它可能发生在用于将参数编组到新的
std::tuple
的 std::thread
创建之前,也可能发生在创建之后。
粗略的伪代码:
std::thread bob( func, arg1, arg2 );
是
std::thread ctor( F&& func, A1&&, arg1, A2&&, arg2 ) {
using package_t = std::tuple<std::decay_t<F>, std::decay_t<A1>, std::decay_t<A2>>;
auto* ptmp = new package( std::forward<F>(func), std::forward<A1>(arg1), std::forward<A2>(arg2) );
m_pthread_handle = pthread_create( [](void* p){
auto* ptmp = static_cast<package*>(p);
std::get<0>(*ptmp)( std::get<1>(std::move(*ptmp)), std::get<2>(std::move(*ptmp)) );
delete ptmp;
}, ptmp );
}
但事实是,参数包“ptmp”是在之前创建的,我们可能在线程创建中失败,这一事实并未指定。