C++ 使用 boost 线程和非静态类函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4581476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using boost thread and a non-static class function
提问by contrapsych
So I have done some research, and have found you can create a boost::thread object and have it start with a non-static class function by using "this" and boost::bind etc. It really doesn't make much sense to me and all the examples I could find had the boost::thread object launched within the same class as the function it was starting with so this could be used. I however, am launching the thread in a different class so I'm afraid by using "this", I will be saying the "this" is from the class I am creating the thread from, rather than the one the function is in (I'm probably wrong, I need to learn more about this "this" guy). Here is an example of my source I am having the problem with.
所以我做了一些研究,发现你可以创建一个 boost::thread 对象,并通过使用“this”和 boost::bind 等让它从一个非静态类函数开始。这真的没有多大意义对我和我能找到的所有示例来说,boost::thread 对象都在与它开始的函数相同的类中启动,因此可以使用它。但是,我正在不同的类中启动线程,所以我担心使用“this”,我会说“this”来自我创建线程的类,而不是函数所在的类(我可能错了,我需要更多地了解这个“这个”家伙)。这是我遇到问题的来源示例。
ANNGUI.h
ANNGUI.h
class ANNGUI { private: boost::thread *GUIThread; Main *GUIMain; public: // Creates the entire GUI and all sub-parts. int CreateGUI(); }
ANNGUI.cpp
ANNGUI.cpp
int ANNGUI::CreateGUI() { GUIMain = new Main(); GUIThread = new boost::thread(GUIMain->MainThreadFunc); };
This isn't all the source, but I think my problem is in here somewhere, I know I have to deal with the "this" somehow, but I'm unsure how. I Could use a static function, but I didn't really want to make my variables static either. Thanks.
这不是全部的来源,但我认为我的问题出在某处,我知道我必须以某种方式处理“这个”,但我不确定如何处理。我可以使用静态函数,但我也不想让我的变量成为静态的。谢谢。
Also, Is there any very good resource for using any boost libraries? Their web site documentation seems good, but over my head.
另外,是否有使用任何 boost 库的非常好的资源?他们的网站文档看起来不错,但我无法理解。
回答by Charles Salvia
The this
keyword is used with boost::bind
when the function object you're creating is bound to a object member function. Member functions can't exist apart from instances, so when creating a functor object out of a member function with boost::bind
, you need a pointer to an instance. That's exactly what the this
keyword actually is. If you use the this
keyword within a member function of a class, what you get is a pointer to the current instance of that class.
该this
关键字使用boost::bind
时您正在创建的函数对象绑定到一个对象的成员函数。成员函数不能脱离实例而存在,所以当用 用成员函数创建一个函子对象时boost::bind
,你需要一个指向实例的指针。这正是this
关键字的实际含义。如果this
在类的成员函数中使用关键字,则得到的是指向该类当前实例的指针。
If you were to call bind
from outsidea class member function, you might say something like:
如果您bind
要从类成员函数外部调用,您可能会这样说:
int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}
Here, we're using Foo::some_function as our thread function. But we can't use this
because we're calling bind
from main
. But the same thing could be achieved using this
if we called bind
from within a member function of Foo, like so:
在这里,我们使用 Foo::some_function 作为我们的线程函数。但是我们不能使用,this
因为我们是bind
从main
. 但是this
如果我们bind
从 Foo 的成员函数中调用,也可以实现同样的事情,如下所示:
void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}
If a member function is static, or is simply a regular (non-member) function, then you don't need an instance pointer at all. You would just do:
如果成员函数是静态的,或者只是一个常规(非成员)函数,那么您根本不需要实例指针。你会这样做:
boost::thread* thr = new boost::thread(some_regular_function);
回答by maxschlepzig
As others mentioned, when you want to call an object method in a new thread, you have to supply the address of that object. But you don't need to call boost::bind
, you can use the overloaded boost::thread
constructor like this:
正如其他人提到的,当您想在新线程中调用对象方法时,您必须提供该对象的地址。但是你不需要调用boost::bind
,你可以boost::thread
像这样使用重载的构造函数:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
If the method is in the same class you use this
to get the address of the current instance, e.g.:
如果该方法在您this
用来获取当前实例地址的同一个类中,例如:
t = new boost::thread(&myclass::compute, this);
If the method has parameters, you can specify them after the second argument, e.g.:
如果方法有参数,您可以在第二个参数后指定它们,例如:
t = new boost::thread(&myclass::compute, this, p1, p2);
回答by villintehaspam
boost::bind is your friend (it can sometimes have a rough way of showing it though)!
boost::bind 是你的朋友(虽然它有时会以粗略的方式显示它)!
use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
用 GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
and then make your MainThreadFunc a regular member. That means that you can use the instance variables directly like you would normally do.
然后使您的 MainThreadFunc 成为常规成员。这意味着您可以像通常那样直接使用实例变量。
Something like this:
像这样的东西:
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;
};
回答by Giuseppe Ottaviano
In cases like this it is useful to think of non-static member functions as free functions that take the this
as first parameter, for example in your case void MainThreadFunc(Main* this)
.
在这种情况下,将非静态成员函数视为采用this
作为第一个参数的自由函数是很有用的,例如在您的情况下void MainThreadFunc(Main* this)
。
boost::thread
accepts a nullary functor, so you have to pass it a nullary functor which contains a reference to the instance GUIMain
and calls GUIMain->MainThreadFunc
which, seen as I explained above, would be something like MainThreadFunc(GUIMain)
.
boost::thread
接受一个空函子,所以你必须向它传递一个空函子,其中包含对实例的引用GUIMain
和调用GUIMain->MainThreadFunc
,正如我上面解释的那样,就像MainThreadFunc(GUIMain)
.
Boost (and now also C++ with TR1) provides helpers to create such functors, namely boost::bind
(or alternatively boost::lambda::bind
). The expression boost::bind(f, arg1, arg2, ...)
means "return a nullary functor which calls f(arg1, arg2, ...)
".
Boost(现在还有带有 TR1 的 C++)提供帮助器来创建这样的函子,即boost::bind
(或替代地boost::lambda::bind
)。该表达式的boost::bind(f, arg1, arg2, ...)
意思是“返回一个调用的空函子f(arg1, arg2, ...)
”。
That said, you can use the following expression to create the thread:
也就是说,您可以使用以下表达式来创建线程:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
回答by Bulletmagnet
If your object is a functor, i.e. has an operator()
, you can pass an instance of it to boost::thread
. The operator()
does not need to be static. For example:
如果您的对象是一个函子,即有一个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;
}