使用boost线程和一个非静态类函数
所以我做了一些研究,发现你可以创build一个boost :: thread对象,并通过使用“this”和boost :: bind等方法来启动一个非静态的类函数。这真的没什么意义对我来说,我可以find的所有例子都有boost :: thread对象在同一个类中作为函数启动,因此可以使用它。 然而,我正在启动另一个类的线程,所以我害怕通过使用“this”,我会说“这个”来自于我创build线程的类,而不是函数所在的类我可能是错的,我需要更多地了解这个“这个”)。 以下是我遇到问题的源代码示例。
ANNGUI.h
class级ANNGUI { 私人的: boost :: thread * GUIThread; 主要* GUIMain; 上市: //创build整个GUI和所有子部分。 int CreateGUI(); }
ANNGUI.cpp
int ANNGUI :: CreateGUI() { GUIMain = new Main(); GUIThread = new boost :: thread(GUIMain-> MainThreadFunc); };
这不是所有的来源,但我认为我的问题是在这里某处,我知道我必须以某种方式处理这个“这个”,但我不确定如何。 我可以使用静态函数,但我真的不想让我的variables静态。 谢谢。
另外,有什么非常好的资源使用任何boost库? 他们的网站文件似乎不错,但在我的头上。
当你正在创build的函数对象绑定到一个对象成员函数时, this
关键字和boost::bind
一起使用。 成员函数不能与实例分开存在,因此当使用boost::bind
从成员函数中创build一个函子对象时,需要一个指向实例的指针。 这正是this
关键字实际上是什么。 如果在类的成员函数中使用this
关键字,则会得到指向该类当前实例的指针。
如果你想从类的成员函数外部调用bind
,你可能会这样说:
int main() { Foo f; boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f)); }
在这里,我们使用Foo :: some_function作为我们的线程函数。 但是我们不能使用this
因为我们从main
调用bind
。 但是如果我们从Foo的成员函数中调用bind
话,也可以用同样的办法来实现,就像这样:
void Foo::func1() { boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this)); }
如果一个成员函数是静态的,或者只是一个普通的(非成员)函数,那么你根本不需要实例指针。 你只需要做:
boost::thread* thr = new boost::thread(some_regular_function);
正如其他人提到的,当你想在一个新线程中调用一个对象方法时,你必须提供该对象的地址。 但是你不需要调用boost::bind
,你可以像这样使用重载的boost::thread
构造函数:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
如果方法在同一个类中,则使用this
来获取当前实例的地址,例如:
t = new boost::thread(&myclass::compute, this);
如果方法有参数,可以在第二个参数后面指定它们,例如:
t = new boost::thread(&myclass::compute, this, p1, p2);
boost :: bind是你的朋友(它有时可以通过粗略的方式显示它)!
使用GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
然后让你的MainThreadFunc成为正式成员。 这意味着您可以像通常那样直接使用实例variables。
像这样的东西:
class GUIMain { public: GUIMain() : m_Member(42) {} void MainThreadFunc() { // use all members as you would normally do std::cout << m_Member << std::endl; } private: int m_Member; };
在这种情况下,将非静态成员函数看作是以此函数作为第一个参数的自由函数会很有用,例如void MainThreadFunc(Main* this)
。
boost::thread
接受一个nullary函数,所以你必须传递一个nullary函数,它包含一个GUIMain
实例的引用,并且调用GUIMain->MainThreadFunc
,正如我上面所解释的那样,它就像MainThreadFunc(GUIMain)
。
Boost(现在还包含TR1的C ++)提供了一些助手来创build这样的函子,即boost::bind
(或者boost::lambda::bind
)。 expression式boost::bind(f, arg1, arg2, ...)
意思是“返回一个调用f(arg1, arg2, ...)
”的nullary函子。
也就是说,你可以使用下面的expression式来创build线程:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
如果你的对象是一个函数,即有一个operator()
,你可以将它的一个实例传递给boost::thread
。 operator()
不需要是静态的。 例如:
#include <boost/thread.hpp> struct th { void operator()(); }; void th::operator()() { for (;;) { // stuff } } int main() { th t; boost::thread my_thread( t ); // takes a copy of t ! my_thread.join(); // blocks return 0; }