C++ 线程问题

c++ thread issue

本文关键字:问题 线程 C++      更新时间:2023-10-16

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

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

它不起作用。知道怎么了?

my函数的类型是:

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

您正在将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);

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

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

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

这两者结合在一起可以非正式地称为代表


PThreads 是一个 C 库,要与它进行互操作,您需要一些解决方法:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    void *(*start_routine)(void*),
    void *arg);
我们将类方法

包装在静态类方法中,以便能够将其作为参数传递 start_routine ,我们将传递指向对象本身的指针作为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) .


请注意,如果你有幸拥有一个支持std::thread的现代编译器,你可以使用它而不是pthreads,并使代码更简单 - 你只需要创建一个std::function对象并将其传递给std::thread的构造函数。

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

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