在类向量中线程化成员函数
Posted
技术标签:
【中文标题】在类向量中线程化成员函数【英文标题】:Threading a member function inside a vector of classes 【发布时间】:2009-09-19 20:28:43 【问题描述】:类 MyClass 上市: 无效 DoSomething() ; ;
std::vector<MyClass> A;
int main(int argc, char* const argv[])
MyClass a;
A.push_back(a);
boost::thread newThread(&MyClass::DoSomething, &A.back());
它可以编译,但不出所料,它不起作用。有什么帮助吗?
【问题讨论】:
哎呀,对不起。现在应该编译。 【参考方案1】:第一个问题是您的 main 函数正在生成一个线程,然后立即退出。在进程终止之前,线程几乎没有机会运行。所以至少你需要等待线程完成,你可以通过在main
的末尾添加newThread.join()
来完成,因此:
int main(int argc, char* const argv[])
MyClass a;
A.push_back(a);
boost::thread newThread(&MyClass::DoSomething, &A.back());
newThread.join();
return 0;
另一个问题是线程对象与main
在同一范围内,作为局部变量。虽然您可以在简单的情况下执行此操作,但您需要注意 boost::thread
对象的范围,它需要至少在您希望线程运行时为其提供生命周期。
在对象需要在成员函数上运行线程的情况下,您最好将线程对象封装在对象内,并使用简单的run()
方法来启动工作线程。这样,您可以将所有状态和线程管理以及您可能需要的任何互斥锁和条件变量封装在一个地方。一个简单的例子是这样的:
class Worker
public:
Worker();
void start(int N)
m_Thread = boost::thread(&Worker::processQueue, this, N);
void join()
m_Thread.join();
// Worker thread where all processing occurs
void processQueue(int N);
private:
boost::thread m_Thread;
;
您可能还想添加诸如返回线程状态(例如,正在运行、已完成、等待等)的标志之类的东西。
我注意到您的示例使用了对象实例的向量(即按值存储)。请注意不要无意中执行导致隐式创建副本的操作,因为这可能会导致线程出现各种问题。 (这就是boost::thread
对象不可复制的原因。)
我在threading with Boost 上写了一篇文章,解释了创建线程的各种方法,包括如何在成员函数上运行线程(参见类型 5)。
【讨论】:
这是一篇很棒的文章。我希望在实际的 boost 文档中有这样的东西,我花了很多时间盯着看,在我弄清楚之前,但你的拥有一切:-) 谢谢!我试着写下我在学习时发现缺少的东西。我还有两篇草稿形式的文章,希望能尽快发布。【参考方案2】:(由于缺少其他输入,我假设您正在使用某些 VS 版本,某些 Windows 版本)。
(1) 我假设您正在尝试将 &A.back 作为隐式的“this”参数传递。这不适用于定义为__thiscall 的常规成员函数——这意味着该函数需要 ecx 寄存器中的 'this' 参数和堆栈中的 not 参数。尝试将 DoSomething 声明为 stdcall 或静态(使用明确的“this”参数)。
(2) 删除函数地址。 Boost::thread 构造函数要求第一个参数是“可调用的”按原样:
boost::thread newThread(MyClass::DoSomething, &A.back());
最终可能会奏效。
【讨论】:
以上是关于在类向量中线程化成员函数的主要内容,如果未能解决你的问题,请参考以下文章