一个类的pthread函数

假设我有一个类如

class c { // ... void *print(void *){ cout << "Hello"; } } 

然后我有一个向量c

 vector<c> classes; pthread_t t1; classes.push_back(c()); classes.push_back(c()); 

现在,我想在c.print();上创build一个线程c.print();

以下是给我下面的问题: pthread_create(&t1, NULL, &c[0].print, NULL);

错误输出:无法将参数'3'转换为'void *(tree_item :: )(void )'为'void *( )(void )'为'int pthread_create(pthread_t *,const pthread_attr_t *,void *( ),void *)'

你不能这样写它,因为C ++类的成员函数有一个隐藏的参数传入pthread_create()不知道这个值是什么,所以如果你试图通过强制转换编译器该方法的适当types的函数指针,你会得到一个分段错误。 你必须使用一个静态类方法(没有this参数),或者一个普通的普通函数来引导这个类:

 class C { public: void *hello(void) { std::cout << "Hello, world!" << std::endl; return 0; } static void *hello_helper(void *context) { return ((C *)context)->hello(); } }; ... C c; pthread_t t; pthread_create(&t, NULL, &C::hello_helper, &c); 

我最喜欢处理线程的方法是将其封装在C ++对象中。 这是一个例子:

 class MyThreadClass { public: MyThreadClass() {/* empty */} virtual ~MyThreadClass() {/* empty */} /** Returns true if the thread was successfully started, false if there was an error starting the thread */ bool StartInternalThread() { return (pthread_create(&_thread, NULL, InternalThreadEntryFunc, this) == 0); } /** Will not return until the internal thread has exited. */ void WaitForInternalThreadToExit() { (void) pthread_join(_thread, NULL); } protected: /** Implement this method in your subclass with the code you want your thread to run. */ virtual void InternalThreadEntry() = 0; private: static void * InternalThreadEntryFunc(void * This) {((MyThreadClass *)This)->InternalThreadEntry(); return NULL;} pthread_t _thread; }; 

要使用它,你只需要创build一个MyThreadClass的子类,并且实现InternalThreadEntry()方法来包含你的线程的事件循环。 在删除线程对象之前,你需要调用线程对象上的WaitForInternalThreadToExit()(当然有一些机制来确保线程真正退出,否则WaitForInternalThreadToExit()永远不会返回)

你必须给pthread_create一个匹配它正在寻找的签名的函数。 你传递的东西是行不通的。

你可以实现你喜欢做的任何静态函数,并且可以引用c一个实例并在线程中执行你想要的。 pthread_create被devise成不仅仅是一个函数指针,而是一个指向“上下文”的指针。 在这种情况下,您只需将它传递给一个c的实例的指针。

例如:

 static void* execute_print(void* ctx) { c* cptr = (c*)ctx; cptr->print(); return NULL; } void func() { ... pthread_create(&t1, NULL, execute_print, &c[0]); ... } 

上面的答案是好的,但在我的情况下,第一种方法将函数转换为静态是行不通的。 我试图将现有的代码转换成线程函数,但代码已经有很多引用非静态类成员。 封装到C ++对象的第二种解决scheme工作,但有3层包装来运行一个线程。

我有一个替代的解决scheme,使用现有的C ++构造 – “朋友”function,它适用于我的情况。 一个我如何使用“朋友”的例子(将使用上面相同的例子来展示如何使用朋友将它转换成一个简洁的forms)

  class MyThreadClass { public: MyThreadClass() {/* empty */} virtual ~MyThreadClass() {/* empty */} bool Init() { return (pthread_create(&_thread, NULL, &ThreadEntryFunc, this) == 0); } /** Will not return until the internal thread has exited. */ void WaitForThreadToExit() { (void) pthread_join(_thread, NULL); } private: //our friend function that runs the thread task friend void* ThreadEntryFunc(void *); pthread_t _thread; }; //friend is defined outside of class and without any qualifiers void* ThreadEntryFunc(void *obj_param) { MyThreadClass *thr = ((MyThreadClass *)obj_param); //access all the members using thr-> return NULL; } 

当然,我们可以使用boost :: thread并避免所有这些,但是我试图修改C ++代码以不使用boost(代码仅仅为了这个目的而连接到boost)

我有史以来第一个答案,希望对某人有用:我现在这是一个老问题,但我遇到了与上述问题完全相同的错误,因为我正在编写一个TcpServer类,我正在尝试使用pthreads。 我发现这个问题,我现在明白为什么会这样。 我结束了这样做:

 #include <thread> 

方法来运行线程 – > void* TcpServer::sockethandler(void* lp) {/*code here*/}

我调用它的lambda – > std::thread( [=] { sockethandler((void*)csock); } ).detach();

这对我来说似乎是一个干净的方法。

我的猜测会是这是B / C它被C + + b / c变得有点臃肿你发送一个C + +指针,而不是C函数指针。 显然是有区别的 。 尝试做一个

 (void)(*p)(void) = ((void) *(void)) &c[0].print; //(check my syntax on that cast) 

然后发送p。

我已经完成了你对一个成员函数的操作,但是我在类中使用它,并且使用了一个静态函数 – 我认为它有所不同。

C ++:如何将类成员函数传递给pthread_create()?

http://thispointer.com/c-how-to-pass-class-member-function-to-pthread_create/

 typedef void * (*THREADFUNCPTR)(void *); class C { // ... void *print(void *) { cout << "Hello"; } } pthread_create(&threadId, NULL, (THREADFUNCPTR) &C::print, NULL);