一个类的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);