[英]Passing variadic template to pthread_create
I understand that pthread_create
accepts a void*(*)(void*)
argument and a void*
, so I have made 2 (failed) attempts to wrap a Function and Args...: 我知道pthread_create
接受一个void*(*)(void*)
参数和一个void*
,所以我进行了2次(失败的)尝试来包装Function和Args ...:
a. 一种。 Creating a C-style void *run(void*)
function that will call an std::function
object that was passed to it: 创建一个C样式的void *run(void*)
函数,该函数将调用传递给它的std::function
对象:
class thread
{
public:
typedef std::function<void()> functor_t;
static void* run(void* f)
{
functor_t* functor = (functor_t*)f;
(*functor)();
delete functor;
return nullptr;
}
template<typename Callable, typename... Args>
explicit thread(size_t stack_size, Callable && callable, Args&&... args) {
auto task_ptr = std::make_shared<std::packaged_task<decltype(callable(args...))()>>(
std::bind(std::forward<Callable>(callable), std::placeholders::_1, std::forward<Args>(args)...)
);
functor_t* functor = new functor_t([task_ptr]() {
(*task_ptr)();
});
pthread_attr_t attr = { 0};
if (pthread_attr_init(&attr) == 0)
{
m_joinable = pthread_attr_setstacksize(&attr, stack_size) == 0 &&
pthread_create(&m_id, &attr, &run, functor);
pthread_attr_destroy(&attr);
}
}
private:
pthread_t m_id = -1 ;
bool m_joinable = false ;
};
This causes the following error in GCC 4.8.5: 这会在GCC 4.8.5中导致以下错误:
/usr/include/c++/4.8.2/functional: In instantiation of 'struct std::_Bind_simple(std::_Placeholder<1>, int))(int*)> >()>': /usr/include/c++/4.8.2/future:1284:55: required from 'void std::__future_base::_Task_state<_Fn, _Alloc, _Res(_Args ...)>::_M_run(_Args ...) [with _Fn = std::_Bind(std::_Placeholder<1>, int))(int*)>; /usr/include/c++/4.8.2/功能:在'struct std :: _ Bind_simple(std :: _ Placeholder <1>,int))(int *)>>()>'的实例中:/ usr / include / c ++ / 4.8.2 / future:1284:55:需要'void std :: __ future_base :: _ Task_state <_Fn,_Alloc,_Res(_Args ...)> :: _ M_run(_Args ...)[with _Fn = std :: _ Bind(std :: _ Placeholder <1>,int))(int *)>; _Alloc = std::allocator; _Alloc = std :: allocator; _Res = void; _Res = void; _Args = {}]' thread.cpp:17:1: required from here /usr/include/c++/4.8.2/functional:1697:61: error: no type named 'type' in 'class std::result_of(std::_Placeholder<1>, int))(int*)> >()>' typedef typename result_of<_Callable(_Args...)>::type result_type; _Args = {}]'thread.cpp:17:1:从此处开始需要/usr/include/c++/4.8.2/functional:1697:61:错误:“ class std :: result_of( std :: _ Placeholder <1>,int))(int *)>>()>'typedef类型名result_of <_Callable(_Args ...)> :: type result_type; ^ /usr/include/c++/4.8.2/functional:1727:9: error: no type named 'type' in 'class std::result_of(std::_Placeholder<1>, int))(int*)> >()>' _M_invoke(_Index_tuple<_Indices...>) ^ ^ /usr/include/c++/4.8.2/functional:1727:9:错误:在'class std :: result_of(std :: _ Placeholder <1>,int))(int *)>中没有名为'type'的类型>()>'_M_invoke(_Index_tuple <_Indices ...>)^
b. 湾 Following this example http://coliru.stacked-crooked.com/a/a6c607514601b013 按照此示例http://coliru.stacked-crooked.com/a/a6c607514601b013
class thread
{
public:
template< typename Callable, typename... Args >
explicit thread(size_t stack_size, Callable&& callable, Args&&... args )
{
auto l = new auto([=]{ callable(args...); });
auto te = [](void* rp) -> void*
{
auto p = reinterpret_cast<decltype(l)>(rp);
(*p)();
delete p;
return nullptr;
};
pthread_attr_t attr = { 0};
if (pthread_attr_init(&attr) == 0)
{
m_joinable = pthread_attr_setstacksize(&attr, stack_size) == 0 &&
pthread_create(&m_id, &attr, te, l);
pthread_attr_destroy(&attr);
}
}
private:
pthread_t m_id = -1 ;
bool m_joinable = false ;
};
This is supposed to work in clang, but fails in GCC 4.8.5 with: 这应该可以在clang中使用,但在GCC 4.8.5中将失败,并且:
In file included from thread.cpp:2:0: thread.h: In lambda function: thread.h:82:37: error: parameter packs not expanded with '...': auto l = new auto([=]{ callable(args...); }); 在thread.cpp:2:0包含的文件中:thread.h:在lambda函数中:thread.h:82:37:错误:参数包未使用'...'扩展:自动l =新自动([=] {callable(args ...);}); ^ thread.h:82:37: note: ^ thread.h:82:37:注意:
'args' thread.h:82:41: error: expansion pattern 'args' contains no argument packs auto l = new auto([=]{ callable(args...); }); 'args'thread.h:82:41:错误:扩展模式'args'不包含任何参数包auto l = new auto([=] {callable(args ...);}); ^ thread.h: In instantiation of 'struct thread::thread(size_t, Callable&&, Args&& ...) [with Callable = void ( )(int ); ^ thread.h:在'struct thread :: thread(size_t,Callable &&,Args && ...)的实例中[带有Callable = void( )(int ); Args = {int*}; Args = {int *}; size_t = long unsigned int]::__lambda4': thread.h:82:48: size_t = long unsigned int] :: __ lambda4':thread.h:82:48:
required from 'thread::thread(size_t, Callable&&, Args&& ...) [with Callable = void ( )(int ); 需要来自'thread :: thread(size_t,Callable && ,, Args && ...)[with Callable = void( )(int ); Args = {int*}; Args = {int *}; size_t = long unsigned int]' thread.cpp:14:32: required from here thread.h:82:37: error: using invalid field 'thread::thread(size_t, Callable&&, Args&& ...)::__lambda4::__args' auto l = new auto([=]{ callable(args...); }); size_t = long unsigned int]'thread.cpp:14:32:从此处需要thread.h:82:37:错误:使用无效字段'thread :: thread(size_t,Callable &&,Args && ...):: __ lambda4: :__ args'auto l = new auto([=] {callable(args ...);}); ^ thread.h:83: confused by earlier errors, bailing out ^ thread.h:83:被先前的错误所迷惑,无法解决
Both ran with the follwing main: 两者都与下面的主程序一起运行:
int g=5;
void run(int *i)
{
printf("t\n");
}
int main()
{
gs_thread t(256*1024, &run, &g);
printf("m\n");
t.join();
}
如果从第一个版本中删除std::placeholders::_1,
它将使用gcc进行编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.