使用pthread_create从线程调用类成员函数

时间:2016-06-21 08:46:19

标签: c++ multithreading

以下是代码

#include <iostream>
#include <pthread.h>

using namespace std;

class Base

{
    private:
    public:

        void *threadCall1( void * value)
        {
            cout<<"inside threadCall1"<<endl;

        }

    protected:

};

class Derived
{
    private:
    public:
        void  *threadCall2 ();
    protected:



};


 void *Derived::threadCall2()
{
    cout<<"inside threadCall2"<<endl;

}
int main ()
{
    int k = 2;
    pthread_t t1;
    cout<<"inside main"<<endl;
    Base *b = new Base();

    pthread_create(&t1,NULL,&b->threadCall1,(void *)k);

    return 0;
}

错误

  

main.cc:在函数int main()': main.cc:46: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say&amp; Base :: threadCall1&#39; main.cc:46:错误:不能   转换void*(Base::*)(void*)' to void *()(void )&#39; for argument 3' to int pthread_create(pthread_t *,const pthread_attr_t *,   void *()(void ),void *)&#39;

我同意C ++禁止这个调用,但有什么办法可以使用posix线程调用类成员函数

3 个答案:

答案 0 :(得分:2)

没有&b->threadCall1之类的东西。幸运的是,pthread允许你将void ptr传递给类(你用k填充的那个)。将b作为此void ptr传递给全局(或静态成员)函数,该函数只调用b->threadCall1();,然后将k移动到Base的属性而不是Base :: threadCall1()的参数。

答案 1 :(得分:2)

您可以通过相应调度工作的功能来执行此操作:

#include <iostream>
#include <pthread.h>

struct Base {
    virtual void work() {
        std::cout << "Base::work()\n";
    }

    virtual ~Base() {}
};

struct Derived : public Base {
    void work() override {
        std::cout << "Derived::work()\n";
    }
};

void* thread_adapter(void* obj) {
    Base* p = static_cast<Base*>(obj);
    p->work();
    return nullptr;
}

int main() {
    Derived d;
    pthread_t thread;
    pthread_create(&thread, nullptr, thread_adapter, &d);
    pthread_join(thread, nullptr);
}

Live example

pthread_create接受指向线程函数的任意数据的指针。传递对象的地址,并使用转发功能,例如上面定义的thread_adapter。在适配器函数内部,您可以static_cast将参数返回到线程函数内的Base*并根据需要调用成员函数。

但是,您可能希望查看std::thread库,它以更自然的方式支持此类操作:

#include <iostream>
#include <thread>

struct Base {
    virtual void work() {
        std::cout << "Base::work()\n";
    }

    virtual ~Base() {}
};

struct Derived : public Base {
    void work() override {
        std::cout << "Derived::work()\n";
    }
};

int main() {
    Derived d;
    std::thread t(&Base::work, d);
    t.join();
}

Live example

答案 2 :(得分:1)

您不能将指向成员函数的指针用作线程例程。考虑使用thead上下文结构将需求信息传递给thead例程:

; Whether PHP will read the POST data.
; This option is enabled by default.
; Most likely, you won't want to disable this option globally. It causes $_POST
; and $_FILES to always be empty; the only way you will be able to read the
; POST data will be through the php://input stream wrapper. This can be useful
; to proxy requests or to process the POST data in a memory efficient fashion.
; http://php.net/enable-post-data-reading
enable_post_data_reading = On

; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size=0