我有一个看起来像这样的课:
class MyThread{
private:
pid_t pid;
size_t stack_size;
char* child_stack;
void* child_stack_end;
public:
// --methods--
MyThread(std::function<int(void*)> const& fun) {
stack_size = 1024*10;
child_stack = new char[stack_size];
child_stack_end = child_stack + stack_size;
int (*const* ptr)(void*) = fun.target<int(*)(void*)>();
pid = clone(*ptr, child_stack_end, CLONE_VM |
CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD, 0);
}
}
并且我想用带有lambda的合并排序函数来测试它(不要创建MyThread类的构造函数,而将merge_sort_thread函数的参数+ clone()
需要int(*)(void*)
函数作为1个参数:]
MyThread([first, center](void* arg){
return merge_sort_thread(first, center);
});
然后尝试此代码,它将返回SIGSEGV。我用GDB检查过,变量ptr等于0x0。我该如何解决?
合并排序功能如下:
template<typename T>
static int merge_sort_thread(T first, T last){ // working with pointers
//sorting
}
主要思想是将MyThread类与std :: thread一起使用,带有lambda
std::thread([first, center](){
return merge_sort_thread(first, center);
});
简而言之,你不能。捕获的lambda与函数指针不兼容,因此您对fun.target<int(*)(void*)>
的调用将返回空指针。将其传递给clone
会导致段错误。
这就是clone
具有void* args
参数将任意数据(指向)传递到回调函数中的原因:这有效地实现了捕获的作用。如果要将自定义std::function
传递给clone
,则需要将其包装到带有签名int(void*)
的函数中,该函数在内部将std::function
从其void*
参数中解包并调用。