我尝试使用可变线程函数参数来实现自己的线程创建,如果线程创建失败,这些参数会传递回其源。这是我的问题“如果线程创建失败,线程的参数会发生什么?”.
我在 Win32 上尝试过这个,这是代码:
#include <Windows.h>
#include <iostream>
#include <tuple>
#include <memory>
#include <utility>
using namespace std;
template<typename Fn, typename ... Args>
void xthread( Fn &&fn, Args &&... args )
{
using tupl_t = tuple<decay_t<Fn>, decay_t<Args> ...>;
auto argsSeq = make_index_sequence<sizeof ...(Args)>();
auto thr = []<size_t ... Indices>( index_sequence<Indices ...> )
{
return +[]( LPVOID lpvThreadParam ) -> DWORD
{
tupl_t &tupl = *(tupl_t *)lpvThreadParam;
get<0>( tupl )( get<Indices + 1>( tupl ) ... );
return 0;
};
};
auto fnObj = make_unique<tupl_t>( forward<Fn>( fn ), forward<Args>( args ) ... );
HANDLE hThread = CreateThread( nullptr, 0, thr( argsSeq ), fnObj.get(), 0, nullptr );
if( hThread )
fnObj.reset(),
WaitForSingleObject( hThread, INFINITE );
else
{
auto back = []<typename Dst>( Dst &&dst, auto &&src )
{
if constexpr( is_rvalue_reference_v<Dst> && !is_const_v<Dst> )
dst = move( src );
};
back( forward<Fn>( fn ), get<0>( *fnObj ) );
[&]<size_t ... Indices>( index_sequence<Indices ...> )
{
(back( forward<Args>( args ), get<Indices + 1>( *fnObj.get() ) ), ...);
}( argsSeq );
}
}
int main()
{
string str( "hello world" );
xthread( []( string &str ) { cout << str << endl; }, move( str ) );
}
但是这段代码一定有问题,因为它没有打印 hello world,而是什么也没有打印,即函数对象被正确调用,但它没有看到 str 的正确参数,而只是意外地将内存清空,默认为空字符串。
雷米是对的。这是 main() 线程中元组的早期重置()。现在代码如下所示:
#include <Windows.h>
#include <iostream>
#include <tuple>
#include <memory>
#include <utility>
using namespace std;
template<typename Fn, typename ... Args>
void xthread( Fn &&fn, Args &&... args )
{
using tupl_t = tuple<decay_t<Fn>, decay_t<Args> ...>;
auto argsSeq = make_index_sequence<sizeof ...(Args)>();
auto thr = []<size_t ... Indices>( index_sequence<Indices ...> )
{
return +[]( LPVOID lpvThreadParam ) -> DWORD
{
unique_ptr<tupl_t> pTupl( (tupl_t *)lpvThreadParam );
get<0>( *pTupl )( get<Indices + 1>( *pTupl ) ... );
return 0;
};
};
auto fnObj = make_unique<tupl_t>( forward<Fn>( fn ), forward<Args>( args ) ... );
HANDLE hThread = CreateThread( nullptr, 0, thr( argsSeq ), fnObj.get(), 0, nullptr );
if( hThread )
fnObj.release(),
WaitForSingleObject( hThread, INFINITE );
else
{
auto back = []<typename Dst>( Dst &&dst, auto &&src )
{
if constexpr( is_rvalue_reference_v<Dst> && !is_const_v<Dst> )
dst = move( src );
};
back( forward<Fn>( fn ), get<0>( *fnObj ) );
[&]<size_t ... Indices>( index_sequence<Indices ...> )
{
(back( forward<Args>( args ), get<Indices + 1>( *fnObj.get() ) ), ...);
}( argsSeq );
}
}
int main()
{
string str( "hello world" );
xthread( []( string &str ) { cout << str << endl; }, move( str ) );
}
我在成功创建线程后分离内存并将其附加到线程函数中的新 unique_ptr 。