我知道 pthread_create
接受 void*(*)(void*)
参数和 void*
,所以我做了2次(失败)尝试包装函数和Args ......:
一个 . 创建一个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 ;
};
这会导致GCC 4.8.5中出现以下错误:
/ usr / include / c /4.8.2/functional:实例化'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; _Res = void; _Args = {}]'thread.cpp:17:1:从这里需要/ usr / include / c /4.8.2/functional:1697:61:错误:'class std :: result_of中没有名为'type'的类型( std :: _ Placeholder <1>,int))(int *)>>>()>'typedef typename result_of <_Callable(_Args ...)> :: type result_type; ^ / usr / include / c /4.8.2/functional:1727:9:错误:'class std :: result_of中没有名为'type'的类型(std :: _ Placeholder <1>,int))(int *)> >()>'_M_invoke(_Index_tuple <_Indices ...>)^
湾按照这个例子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 ;
};
这应该在clang中起作用,但在GCC 4.8.5中失败:
在thread.cpp中包含的文件中:2:0:thread.h:在lambda函数中:thread.h:82:37:错误:参数包未使用'...'扩展:auto l = new auto([= ] {callable(args ...);}); ^ thread.h:82:37:注意:'args'strread.h:82:41:错误:扩展模式'args'不包含参数包auto l = new auto([=] {callable(args ...) ;}); ^ thread.h:实例化'struct thread :: thread(size_t,Callable &&,Args && ...)[with Callable = void()(int); Args = {int *}; size_t = long unsigned int] :: __ lambda4':thread.h:82:48:'thread :: thread(size_t,Callable &&,Args && ...)[with Callable = void()(int); Args = {int *}; '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:被早先的错误弄糊涂了,救了出来
两个人都跟随主要人物:
int g=5;
void run(int *i)
{
printf("t\n");
}
int main()
{
gs_thread t(256*1024, &run, &g);
printf("m\n");
t.join();
}
1 回答
如果从第一个版本中删除
std::placeholders::_1,
,则使用gcc进行编译 .