c ++线程问题

时间:2012-07-04 10:33:46

标签: c++ multithreading

我正在尝试使用以下代码在c ++中创建一个线程:

pthread_t mythread;
void* f (void*) = MyClass::myfunction;
pthread_create(&mythread, NULL, &f, NULL);

它不起作用。知道什么是错的吗?

myfunction的类型为:

void* MyClass::myfunction(void* argv);

返回的错误是:

error: declaration of ‘void* Class::f(void*)’ has ‘extern’ and is initialized

error: invalid pure specifier (only ‘= 0’ is allowed) before ‘::’ token

error: function ‘void* Class::f(void*)’ is initialized like a variable

3 个答案:

答案 0 :(得分:6)

您将f声明为函数而不是函数指针。它应该是:

void* (*f) (void*) = &MyClass::myfunction;
      ^^^^

pthread_create(&mythread, NULL, f, NULL);
                                ^ no & since it's already a pointer

这也只有在myfunction是静态的情况下才有效,因为你无法将指向成员的函数转换为指向函数的指针。

如果您确实需要线程在特定对象上执行非静态成员函数,那么一种方法是编写一个静态包装器,将该对象作为参数:

class MyClass {
public:
    void start_thread() {
        // Pass "this" to the thread we're creating
        pthread_create(&mythread, NULL, &MyClass::thread_entry, this);
    }
private:
    static void * thread_entry(void * object) {
        // Call the member function on the object passed to the thread
        return static_cast<MyClass*>(object)->thread();
    }
    void * thread() {
        // do the interesting stuff, with access to the member variables
    }
};

当然,现在有一个标准的线程库,不再需要这种舞蹈:

std::thread thread(&MyClass::thread, this);

答案 1 :(得分:2)

Pthreads需要函数指针,对于类,只能使用函数指针指向静态方法。

如果您想在某个特定对象上调用某个类的特定方法,则需要两个独立的数据部分:

  • 指向类方法的指针(不要将它们与函数指针混淆)
  • 指向对象的指针

这两个连接在一起的可以非正式地称为委托


PThreads是一个C库,为了与之互操作,您需要一些解决方法:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    void *(*start_routine)(void*),
    void *arg);

我们要将类方法包装在一个静态类方法中,以便能够将它作为参数start_routine传递,我们将把指针传递给对象本身{{1} }。

参见代码:

arg

此类解决方法允许您使用struct Foo { // wrapper method static void* threadStartingPoint(void* obj) { return ((Foo)obj)->threadFunc(); } // your target method itself void* threadFunc() { // this is where you do your logic } }


请注意,如果您足够幸运拥有支持pthread_create(thread, attr, Foo::threadStartingPoint, someObject)的现代编译器,则可以使用它而不是pthreads并使代码更简单 - 您只需要创建一个std::thread对象并且将它传递给std::function的构造函数。

答案 2 :(得分:1)

你简单不能做你想做的事 - 一个成员函数(除非它是静态的)需要一个被调用的对象 - 也就是启动线程的进程不能只调用MyClass :: f ()因为它需要调用something.f() - 而且它不知道是什么东西。

通常可以通过定义一个静态成员函数来解决这个问题,该函数将对象作为参数,然后在该对象上调用成员函数。