使用C ++。
pthread_t threads[STORAGE]; // 0-99
...
void run()
Error>>> int status = pthread_create(&threads[0], NULL, updateMessages, (void *) NULL);
if (status != 0)
{
printf("pthread_create returned error code %d\n", status);
exit(-1);
}
...
void ClientHandler::updateMessages(void *)
{
string reqUpdate = "91"; // Request for update
string recvMSG;
while (true)
{
sleep(5);
sending(sock,reqUpdate); // send
recvMSG = receiving(sock); // receive
QString output(recvMSG);
emit signal_chat(output, 0); // Print message to text box
}
}
...
编译错误:
TCPClient.cpp:109: error: argument of type ‘void (ClientHandler::)(void*)’ does not match ‘void* (*)(void*)’
我无法弄清楚什么是错的。 提前谢谢。
答案 0 :(得分:7)
指向成员函数的指针与具有相同签名的全局函数不同,因为成员函数需要一个其操作的附加对象。因此,指向这两种函数的指针不兼容。
在这种情况下,这意味着您不能将成员函数指针传递给pthread_create
,而只能传递指向非成员(或静态)函数的指针。解决此问题的方法是使用pthread_create
的第四个参数将指向对象的指针传递给全局函数,然后全局函数调用传递的对象的方法:
class ClientHandler {
public:
void updateMessages();
void run();
};
// Global function that will be the threads main function.
// It expects a pointer to a ClientHandler object.
extern "C"
void *CH_updateMessages(void *ch) {
// Call "real" main function
reinterpret_cast<ClientHandler*>(ch)->updateMessages();
return 0;
}
void ClientHandler::run() {
// Start thread and pass pointer to the current object
int status = pthread_create(&threads[0], NULL, CH_updateMessages, (void*)this);
...
}
答案 1 :(得分:6)
它与线程无关,这是一个正常的C ++错误,你只是传递一个不兼容的函数指针类型。
函数指针与成员实例函数指针不同,即使它们的签名相同;这是因为有一个隐含的引用* this传递。你无法避免这种情况。
答案 2 :(得分:0)
当pthread_create采用自由函数时,在ClientHandler中创建一个静态函数(是一个自由函数)
static void Callback(void * this_pointer,int other_arg) {
ClientHandler* self = static_cast< ClientHandler*>(this_pointer);
self-> updateMessages(other_arg);
}
and call pthread_create as follows
pthread_create(&threads[0], NULL, &ClientHandler::Callback, (void *) pointer_to_ClientHandler,int other_arg);
这有效,因为Callback是免费功能
答案 3 :(得分:0)
YoLinux有一个很好的pthread教程,我帮助你学习线程。
答案 4 :(得分:0)
正如其他人已经说过的那样,问题是功能之间的签名是不同的。类成员函数始终具有“秘密”额外参数this
指针。因此,您永远不能传递期望全局函数的成员函数。您可以使用诸如Boost.Bind之类的库来解决这个问题,或者将该函数作为该类的静态成员。
但最简单,最优雅的解决方案是使用不同的线程API。
Boost.Thread是一个非常好的C ++线程库(pthreads是为C设计的,这就是为什么它不能很好地运用类方法等C ++特性)。
我建议使用它。
您的代码可以重写为:
class ClientHandler {
public:
ClientHandler(/* All the parameters you want to pass to the thread. Unlike pthreads you have complete type safety and can pass as many parameters to this constructor as you like */){...}
void operator()() // boost.thread calls operator() to run the thread, with no parameters. (Since all parameters were passed in the constructor and saved as member variables
{
string reqUpdate = "91"; // Request for update
string recvMSG;
while (true)
{
sleep(5);
sending(sock,reqUpdate); // send
recvMSG = receiving(sock); // receive
QString output(recvMSG);
emit signal_chat(output, 0); // Print message to text box
}
}
// whatever arguments you want to pass to the thread can be stored here as member variables
};
boost::threead_group gr; // can store all your threads here, rather than being limited to your fixed-size array
gr.create_thread(ClientHandler(/* construct a ClientHandler object with the parameters you like*/));
答案 5 :(得分:-1)
您传递的是成员函数而不是全局的普通函数。
只需定义:
void updateMessages(void *) {
static ClientHandler c;
// use c..
}