Best way to start a thread as a member of a C++ cl

2019-01-13 18:35发布

I'm wondering the best way to start a pthread that is a member of a C++ class? My own approach follows as an answer...

标签: c++ pthreads
5条回答
我只想做你的唯一
2楼-- · 2019-01-13 19:15

You have to bootstrap it using the void* parameter:

class A
{
  static void* StaticThreadProc(void *arg)
  {
    return reinterpret_cast<A*>(arg)->ThreadProc();
  }

  void* ThreadProc(void)
  {
    // do stuff
  }
};

...

pthread_t theThread;
pthread_create(&theThread, NULL, &A::StaticThreadProc, this);
查看更多
叼着烟拽天下
3楼-- · 2019-01-13 19:19

I have used three of the methods outlined above. When I first used threading in c++ I used static member functions, then friend functions and finally the BOOST libraries. Currently I prefer BOOST. Over the past several years I've become quite the BOOST bigot.

BOOST is to C++ as CPAN is to Perl. :)

查看更多
贼婆χ
4楼-- · 2019-01-13 19:38

I usually use a static member function of the class, and use a pointer to the class as the void * parameter. That function can then either perform thread processing, or call another non-static member function with the class reference. That function can then reference all class members without awkward syntax.

查看更多
在下西门庆
5楼-- · 2019-01-13 19:38

The boost library provides a copy mechanism, which helps to transfer object information to the new thread. In the other boost example boost::bind will be copied with a pointer, which is also just copied. So you'll have to take care for the validity of your object to prevent a dangling pointer. If you implement the operator() and provide a copy constructor instead and pass the object directly, you don't have to care about it.

A much nicer solution, which prevents a lot of trouble:

#include <boost/thread.hpp>

class MyClass {
public:
        MyClass(int i);
        MyClass(const MyClass& myClass);  // Copy-Constructor
        void operator()() const;          // entry point for the new thread

        virtual void doSomething();       // Now you can use virtual functions

private:
        int i;                            // and also fields very easily
};

MyClass clazz(1);
// Passing the object directly will create a copy internally
// Now you don't have to worry about the validity of the clazz object above
// after starting the other thread
// The operator() will be executed for the new thread.
boost::thread thread(clazz);             // create the object on the stack

The other boost example creates the thread object on the heap, although there is no sense to do it.

查看更多
Melony?
6楼-- · 2019-01-13 19:41

This can be simply done by using the boost library, like this:

#include <boost/thread.hpp>

// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}

// construct an instance of the widget modeller or controller
cWidget theWidget;

// start new thread by invoking method run on theWidget instance

boost::thread* pThread = new boost::thread(
    &cWidget::Run,      // pointer to member function to execute in thread
    &theWidget);        // pointer to instance of class

Notes:

  • This uses an ordinary class member function. There is no need to add extra, static members which confuse your class interface
  • Just include boost/thread.hpp in the source file where you start the thread. If you are just starting with boost, all the rest of that large and intimidating package can be ignored.

In C++11 you can do the same but without boost

// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}

// construct an instance of the widget modeller or controller
cWidget theWidget;

// start new thread by invoking method run on theWidget instance

std::thread * pThread = new std::thread(
    &cWidget::Run,      // pointer to member function to execute in thread
    &theWidget);        // pointer to instance of class
查看更多
登录 后发表回答