pthread_create参数函数指针

时间:2011-10-19 11:30:34

标签: c++ function pointers pthreads

我正在尝试在以下代码中创建一个线程,但是指向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

编辑:run()是类RobotNodes.cpp中的一个方法,它包含在这个类的顶部。

3 个答案:

答案 0 :(得分:4)

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的向量;这是因为如果它们是不同的线程,每个线程实例必须是不同的,而且,即使在循环停止之后,每个线程实例也必须继续存在

答案 1 :(得分:0)

运行定义在哪里?

使用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之类的静态函数,向它传递一个指向要调用该函数的类实例的指针。

答案 2 :(得分:0)

问题是你试图指定一个指向成员函数的指针,而不是标准函数。

相反,将机器人作为参数传递给一个告诉机器人运行的函数:

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