16

我想知道启动作为 C++ 类成员的 pthread的最佳方法?我自己的方法如下作为答案......

4

5 回答 5

23

这可以通过使用 boost 库来简单地完成,如下所示:

#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

笔记:

  • 这使用了一个普通的类成员函数。无需添加额外的静态成员来混淆您的类接口
  • 只需在启动线程的源文件中包含 boost/thread.hpp 即可。如果您刚开始使用 boost,那么所有其余的大而令人生畏的软件包都可以忽略不计。

在 C++11 中,你可以做同样的事情,但不需要提升

// 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
于 2008-09-17T18:41:56.977 回答
15

我通常使用类的静态成员函数,并使用指向类的指针作为 void * 参数。然后该函数可以执行线程处理,或者使用类引用调用另一个非静态成员函数。然后,该函数可以引用所有类成员,而不会使用笨拙的语法。

于 2008-09-17T18:27:15.017 回答
11

您必须使用 void* 参数引导它:

A级
{
  静态无效*静态线程过程(无效*arg)
  {
    return reinterpret_cast<A*>(arg)->ThreadProc();
  }

  无效* ThreadProc(无效)
  {
    // 做东西
  }
};

...

pthread_t 线程;
pthread_create(&theThread, NULL, &A::StaticThreadProc, this);
于 2008-09-17T18:32:30.277 回答
3

我使用了上述三种方法。当我第一次在 c++ 中使用线程时,我使用了静态成员函数,然后是友元函数,最后是BOOST 库。目前我更喜欢BOOST。在过去的几年里,我已经成为了 BOOST 的偏执狂。

BOOST 之于 C++,就像 CPAN 之于 Perl。:)

于 2008-09-17T20:28:55.130 回答
0

boost 库提供了一种复制机制,有助于将对象信息传输到新线程。在另一个 boost 示例中, boost::bind 将使用指针进行复制,该指针也只是被复制。因此,您必须注意对象的有效性,以防止出现悬空指针。如果你实现 operator() 并提供一个复制构造函数并直接传递对象,你不必关心它。

一个更好的解决方案,可以避免很多麻烦:

#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

另一个 boost 示例在堆上创建线程对象,尽管这样做没有意义。

于 2010-05-11T16:29:02.867 回答