Как я могу передать указатель на функцию из std :: function к клону Linux? - PullRequest
1 голос
/ 11 января 2020

У меня есть класс, который выглядит следующим образом:

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);
    }
}

И я хочу проверить его с помощью функции сортировки слиянием с помощью лямбды (не для создания конструктора класса 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 с лямбда

std::thread([first, center](){
    return merge_sort_thread(first, center);
});

1 Ответ

3 голосов
/ 11 января 2020

Проще говоря, вы не можете. Захватывающая лямбда не совместима с указателем на функцию, и ваш вызов fun.target<int(*)(void*)>, следовательно, возвращает нулевой указатель. Передача этого в clone вызывает ошибку по умолчанию.

Именно поэтому clone имеет аргумент void* args для передачи (указателя) произвольных данных в функцию обратного вызова: это эффективно выполняет роль захвата. Если вы хотите передать пользовательский std::function в clone, вам нужно будет обернуть его в функцию с подписью int(void*), которая внутренне разворачивает этот std::function из аргумента void* и вызывает его.

...