我正在使用pthread
为我自己实现线程类。所以,我创建了Thread
类,如下所示:
class Thread
{
public:
Thread()
{
}
virtual void* run(void *params) = 0;
void start(void *params)
{
pthread_create (&threadId, 0, run, params);
pthread_join (threadId, 0);
}
private:
pthread_t threadId;
};
实现这个类并重写virtual run
函数后,我编译了这个项目。但是error: argument of type ‘void* (Thread::)(void*)’ does not match ‘void* (*)(void*)’
发生了。我的代码出了什么问题?
提前致谢:)
答案 0 :(得分:3)
正是编译器告诉你的内容。
pthread_create期待一个带签名的函数:
void* (*)(void*)
哪个是函数指针。
但是,您提供的是此签名:
void* (Thread::)(void*)
不是函数指针,而是指向成员函数的指针。有一点不同:指向成员函数的指针需要一个对象的实例才能正常工作(这里需要一个Thread实例)。
通常的解决方案是使你的函数run
static
:它不再是一个成员函数 - 它不再需要一个Thread实例才能正常工作,而你可以将当前实例作为pthread_create
的最后一个参数传递,以便在线程启动后对其执行操作。
您只需要在类本身中保存参数。
public:
void start(void *params)
{
this->my_thread_params = params;
pthread_create (&threadId, 0, run, static_cast<void*>(this));
}
private:
static void *run(void *my_object)
{
// here, my_object already contains the params you passed to the function start
static_cast<Thread*>(my_object)->my_member_function();
}
答案 1 :(得分:2)
错误消息告诉您指向Thread
中的成员函数的指针,该成员函数获取并返回void*
(void* (Thread::*)(void*)
)不能转换为函数获取和返回的指针同样的void*
。
虽然成员函数的声明可能看起来与您需要的类型相似,但是this
类型的隐式Thread
指针需要在对{{1}的任何调用时注入}
答案 2 :(得分:2)
pthread_create
是一个C函数,对C ++成员函数一无所知。您需要为其提供静态或非成员函数,并通过Thread
的最终参数将指针传递给pthread_create
对象;类似的东西:
class Thread
{
virtual void* run(void *params) = 0;
void start(void * params)
{
this->params = params;
pthread_create(&threadId, 0, &Thread::static_run, this);
}
static void * static_run(void * void_this)
{
Thread * thread_this = static_cast<Thread*>(void_this);
return thread_this->run(thread_this->params);
}
private:
pthread_t threadId;
void *params;
};
当然在现代C ++中,这更为直白:
std::thread thread;
void start(void * params)
{
thread = std::thread([this]{run(params);});
}
(虽然你当然不应该使用void*
来传递你的参数,并且可能没有充分的理由将线程首先包装在一个类中。)