启动线程作为C ++类成员的最佳方法?
时间:2020-03-05 18:59:35 来源:igfitidea点击:
我想知道启动作为C ++类成员的pthread的最佳方法吗?我自己的方法可以作为答案...
解决方案
回答
我通常使用该类的静态成员函数,并使用指向该类的指针作为void *参数。然后,该函数可以执行线程处理,或者使用类引用调用另一个非静态成员函数。然后,该函数可以引用所有类成员,而无需使用笨拙的语法。
回答
我们必须使用void *参数来引导它:
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);
回答
这可以通过使用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
回答
我使用了上面概述的三种方法。
当我第一次在c ++中使用线程时,我使用了静态成员函数,然后是朋友函数,最后是BOOST库。目前,我更喜欢BOOST。在过去的几年中,我已经成为BOOST的顽固派。
BOOST对C ++来说就像CPAN对Perl一样。 :)
回答
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示例在堆上创建线程对象,尽管没有意义。