将类方法作为 pthread start 函数传递



考虑以下类

class Foo
{
    public:
        void* func(void* arg)
        {
            // how to pass this function to pthread...?!
        }
}

稍后我想将func()传递给pthread_create(),而不是函数:

int main()
{
    char * msg = "Hi dude";
    Foo * ins = new Foo();
    pthread_t pt;
    // how to pass ins->func instead of a function?
    pthread_create( &pt, NULL, ins->func, (void*)msg );
}

提前谢谢。

"通常"的方法是,将对象和所有函数参数打包到一个结构中,在堆上分配此结构,将此结构的实例传递给具有 C 绑定的函数,并让该函数调用对象成员函数:

struct wrap {
    char * msg;
    Foo ins; 
    wrap( char* m, const Foo& f ) : msg(m), ins(f) {}
};
extern "C" void* call_func( void *f )
{
    std::auto_ptr< wrap > w( static_cast< wrap* >( f ) );
    w->ins.func(w->msg);
    return 0;
}
int main() {
    wrap* w = new wrap( "Hi dude", Foo() );
    pthread_t pt;
    pthread_create( &pt, NULL, call_func, w );
}

它不能按照您尝试的方式工作C++因为成员函数获取作为其第一个参数传递的对象this指针。如果处于C++模式,编译器隐式执行此操作。

但是,pthread_create()是一个 C 函数。它的第三个参数是"指向将void *作为参数(并返回void *)的函数的指针"。一旦进入pthread_create(),就没有this,没有信息this应该隐式传递为第一个参数......并且成员函数的调用方式与预期调用的方式非常不同 - 您遇到了各种各样的麻烦。

这就是为什么pthread_create()只适用于使用"C"链接的函数:全局函数和静态成员函数(两者都不使用this指针)。

Torsten有一个很好的方法来绕过这个限制。我只是想详细说明一下问题的技术背景。

一种方法是将函数声明为静态

#include <iostream>
#include <pthread.h>
class Foo {
  public:
    static void* func(void* arg) {
      char *test = (char *) arg;
      std::cout << test << std::endl;
    }
};
int main() {
  char * msg = "Hi dude";
  Foo ins;
  pthread_t pt;
  pthread_create( &pt, NULL, ins.func, (void*)msg );
  pthread_join(pt, NULL);
  return 0;
}

相关内容

最新更新