本文介绍了C ++:如何定义一个类方法作为线程的启动例程(使用pthread库)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基本类和派生类。
他们有一个虚拟函数 - virtual void action()
我如何将它传递给* pthread_create()* function?

i have a Base class and Derived class.they have a virtual function- virtual void action()how can i pass it to *pthread_create()* function?

示例(含错误):

class Base{
  protected:
     pthread_t tid;
  public:
  virtual void* action() = 0;
};

class Derived : public Base{
  void* action();
  Derived(){
    pthread_create(&tid, NULL, &action, NULL);
  }
};

也许应该是静态的?
i尝试了很多组合但找不到解决方案。

maybe it should be static?i tried lot of combinations but cant find solution..

推荐答案

我碰到这个问题几个月后我的高级设计项目。它需要一些底层C ++机制的知识。

I ran into this problem a couple months back working on my senior design project. It requires some knowledge of underlying C++ mechanics.

底层的问题是函数的指针不同于指向成员函数的指针。这是因为成员函数有一个隐式的第一个参数, this

The underlying issue is that pointers to functions are different from pointers to member functions. This is because member functions have an implicit first parameter, this.

man 页面:

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

线程入口点是 void *(*)(void *) 。您的函数 Base :: action 的类型为 void *(Base :: *)()。该丑陋类型声明的 Base :: 部分表示 this 的类型。类型差异是为什么编译器不接受您的代码。

The thread entrance point is a void* (*)(void*). Your function, Base::action has the type void* (Base::*)(). The Base:: part of that ugly type declaration denotes the type of this. The type discrepancy is why the compiler won't accept your code.

有两件事我们需要修复,使这项工作。我们不能使用成员函数,因为指向成员函数的指针不会将 this 绑定到实例。我们还需要一个类型 void * 的参数。幸运的是,这两个修正是相辅相成的,因为解决方案是显式地通过 this

There's two things we need to fix to make this work. We can't use a member function, because pointers to member functions don't bind this to an instance. We also need a single parameter of type void*. Thankfully, these two fixes go hand in hand because the solution is to explicitly pass this ourselves.

class Base {
public:
    virtual void* action() = 0;

protected:
    pthread_t tid;

    friend void* do_action(void* arg) {
        return static_cast<Base*>(arg)->action();
    }
};

class Derived : public Base {
public:
    Derived() {
        // This should be moved out of the constructor because this
        // may (will?) be accessed before the constructor has finished.
        // Because action is virtual, you can move this to a new member
        // function of Base. This also means tid can be private.
        pthread_create(&tid, NULL, &do_action, this);
    }

    virtual void* action();
};

编辑:如果 tid protected private ,然后 do_action 需要是朋友

Woops, if tid is protected or private, then do_action needs to be a friend.

这篇关于C ++:如何定义一个类方法作为线程的启动例程(使用pthread库)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 05:54
查看更多