在类向量中线程化成员函数

时间:2009-09-19 20:28:44

标签: c++ boost multithreading

类MyClass     {     上市:         void 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());
}

它编译,但是,预计它不起作用。有什么帮助吗?

2 个答案:

答案 0 :(得分:4)

第一个问题是你的主要功能是产生一个线程,然后立即退出。在进程终止之前,该线程几乎没有机会运行。因此,您至少需要等待线程完成,您可以通过将newThread.join()添加到main的末尾来执行此操作,因此:

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)。

答案 1 :(得分:0)

(由于缺少其他输入,我假设您正在使用某些Windows版本的某些VS版本。)

(1)我假设你试图将&amp; A.back作为隐含的'this'参数传递。这不适用于常规成员函数,它定义为__thiscall - 这意味着函数需要ecx寄存器中的'this'参数和堆栈中的 not 。尝试将DoSomething声明为stdcall或static(带有明确的'this'参数)。

(2)删除功能地址。 Boost :: thread构造函数要求第一个参数为'callable',而不是

boost::thread newThread(MyClass::DoSomething, &A.back());

可能最终有效。