我正在尝试在以下代码中创建一个线程,但是指向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中的一个方法,它包含在这个类的顶部。
答案 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]);