указатель на функцию параметра pthread_create - PullRequest
1 голос
/ 19 октября 2011

Я пытаюсь создать поток в следующем коде, но указатель на параметр функции вызова метода pthread_create просто не позволяет мне скомпилировать мой код.

Пожалуйста, дайте мне знать, что я делаю неправильно и как я могу это исправить в следующем коде:

#include "RobotNodes.cpp"

int main(int argc, char** argv){

int i, numRobotsToInit = 7;

//declare run function pointer
void (*run)();

//create array of robot nodes 
RobotNodes* robots[numRobotsToInit]; 

//init robot nodes
for(i = 0; i<numRobotsToInit; i++){
    robots[i] = new RobotNodes(i, 0.2, 0.2);
}


for(i = 0; i<numRobotsToInit; i++){
        run = &robots[i]->run;
        pthread_t thread; 
    pthread_create(&thread, NULL, (void*(*)(void*))run, NULL);       
}
}

Я получаю следующую ошибку: error: lvalue required as unary ‘&’ operand

Edit: run () - это метод из класса RobotNodes.cpp, который включен в начало этого класса.

Ответы [ 3 ]

4 голосов
/ 19 октября 2011

Кажется, что нестатическая функция-член в классе RobotNodes, и вы, кажется, думаете, что тип функции-члена void (*)().Если так, то вы не правы.

Тип нестатического члена-функции и свободной функции не совпадают, даже если они имеют абсолютно одинаковую сигнатуру!

Поэтому я бы предложил вам определить статическийфункция называется start, как:

class RobotNodes
{
   public:
        void run(); //define it as you like

        static void* start(void *pdata)
        {
             RobotNodes *robot = static_cast<RobotNodes*>(pdata);
             robot->run(); //forward it
             return 0; //or return as the documentation says
        }
};

Затем используйте start как:

std::vector<pthread_t> threads(numRobotsToInit);
for(i = 0; i<numRobotsToInit; i++)
{
    pthread_create(&threads[i], NULL, RobotNodes::start, &robots[i]);       
}

Также обратите внимание, что я создал вектор pthread_t вне цикла;это связано с тем, что каждый экземпляр thread должен отличаться, если он является другим потоком, и, кроме того, каждый экземпляр должен продолжать существовать даже после остановки цикла.

0 голосов
/ 19 октября 2011

проблема в том, что вы пытаетесь указать указатель на функцию-член, а не на стандартную функцию.

Вместо этого передайте робота в качестве параметра функции, которая сообщает роботу:

extern "C" void* run_robot(void* robot) __attribute__((noreturn));
void* run_robot(void* robot) {
    RobotNodes* node(static_cast<RobotNodes*>(robot));
    node->run();
    pthread_exit(0);
}
...
pthread_create(&thread, NULL, run_robot, &robots[i]);
0 голосов
/ 19 октября 2011

Где определен прогон?

Использование pthread_create(&thread, ...) плохо, поскольку thread переменная локальная для цикла for и выйдет из области видимости в конце for.

попробуйте вместо этого:

for(i = 0; i<numRobotsToInit; i++){
  run = &robots[i]->run;
  pthread_t* thread = new pthread_t;  //you will get a memory leak unless you store these to delete later
  pthread_create(thread, NULL, run, NULL);       
}

Если я правильно понял, функция run является членом RobotNodes, в этом случае вам нужно сделать диспетчер для вызова этой функции, так как вы не можете передать функции-члены pthread_create.

Создайте статическую функцию с именем dispatch или что-то еще, передайте ей указатель на экземпляр класса, для которого вы хотите вызвать функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...