【问题标题】:pthread create error in c++ [duplicate]c++中的pthread创建错误[重复]
【发布时间】:2011-06-15 02:15:00
【问题描述】:

可能重复:
pthread Function from a Class

我收到一个错误(“无法转换.....”),我认为 pthread_create 调用中的第三个参数是错误的。我知道第三个参数的类型应该是 (void*)*(void *) 但我仍然收到错误。

void ServerManager::Init(){  
     pthread_t thread;
     pthread_create(&thread, NULL, AcceptLoop, (void *)this);
}

我已经这样声明了,我正在尝试调用下面的函数

void* ServerManager::AcceptLoop(void * delegate){

}

请告诉我如何解决这个问题..

提前致谢。

【问题讨论】:

标签: c++ pthreads


【解决方案1】:

为了便于移植,回调函数必须使用 C ABI;

extern "C" void* AcceptLoop(void*);

class ServerManager 
{
    public:
       void  Init();

    private:
       friend void* AcceptLoop(void*);

       void* AcceptLoop();   // Implement this yourself
       pthread_t thread;
};

void ServerManager::Init()
{  
     pthread_create(&thread, NULL, &AcceptLoop, reinterpret_cast<void*>(this));
}

void* AcceptLoop(void* delegate)
{
    return reinterpret_cast<ServerManager*>(delegate)->AcceptLoop();
}

void* ServerManager::AcceptLoop()
{
    // Do stuff
    // Be carefull this may (or may not) start before ServerManager::Init() returns.
    return NULL;
}

编辑:基于评论

pthread_join()

这将等待特定线程退出。调用 pthread_create() 的线程可以调用 pthread_join() 来等待子进程完成。这样做的一个好地方是(可能)将连接放在 ServerManager 的析构函数中。

pthread_cancel()

pthread_cancel() 是线程停止的异步请求。调用将立即返回(因此并不意味着线程已经死了)。未指定它将以多快的速度停止执行您的代码,但它应该执行一些整洁的处理程序然后退出。使用 pthread_jon() 等待取消的线程是个好主意。

class ServerManager 
{
    public:
       void  ~ServerManager()
       {
           join();
       }
       void* join()
       {
           void*   result;
           pthread_join(thread, &result);
           return result;
       }
       void cancel()
       {
           pthread_cancel(thread);
           join();
       }
       ... like before
};

【讨论】:

  • 感谢您的回答。我还有一个问题。关闭此线程的最佳方法是什么?我已阅读 pthread_join 或 pthread_cancel 但我不确定哪个更好。提前致谢。
  • @LCYSoft:已更新。 PS。你可能想看看 boost::thread。它更先进且易于使用。 pthread 接口并不适合初学者。
【解决方案2】:

您需要将 AcceptLoop(void*) 设为静态函数。

例子:

class ServerManager {
    // ...
    static void* AcceptLoop(void*);
    void* AcceptLoop();   // Implement this yourself
};

void* ServerManager::AcceptLoop(void* delegate)
{
    return static_cast<ServerManager*>(delegate)->AcceptLoop();
}

【讨论】:

  • 感谢您的回答。但是有没有其他方法可以做到这一点,比如使用函数指针?
  • @LCYSoft:你可以获得静态函数的函数指针。
  • pthread_create() 调用中指定的静态函数可以为所欲为 - 如果你给它一个函数指针,或者通过最后一个 void* 参数到 pthread_create(),它作为唯一的静态函数的参数,或者事先任何你喜欢的,然后它可以调用它。注意:无论如何都不能在不知道对象地址的情况下调用指向成员函数的指针。除非您想改变在运行时调用的成员函数,否则 Chris 的解决方案比使用函数指针更简单更好 - btw "delegate" = ServerManager 对象的 addr。
  • 由于 pthreads 是一个 C 库,因此回调必须使用 C ABI。 唯一 保证这一点的方法是使“AcceptLoop()”成为外部“C”,您很幸运,您的编译器对静态方法使用相同的 ABI。
  • @Martin:+1 确实如此。我考虑过修复它,但看来你的回答已经解决了这个问题。 :-)
猜你喜欢
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多