【问题标题】:Thread updating the class object线程更新类对象
【发布时间】:2013-02-01 20:43:04
【问题描述】:

如何从线程中返回一个类对象或者如何保持它的状态?

struct DataStructure
{
    MapSmoother *m1;
    std::vector<Vertex*> v1;
    std::vector<Vertex *>::iterator vit;

    DataStructure() {
        m1 = NULL;
        v1;
        vit;
    }
};

DWORD WINAPI thread_fun(void* p)
{
        DataStructure *input = (DataStructure*)p;
        for( ; (input->vit) != (input->v1).end(); ){
            Vertex *v = *input->vit++;
                (*(input->m1)).relax(v);
        }
        return 0;
}
main()
{
//Reading srcMesh
//All the vertices in srcMesh will be encoded with color
MapSmoother msmoother(srcMesh,dstMesh); //initial dstMesh will be created with no edge weights 
DataStructure* input = new DataStructure; //struct datatype which holds msmoother object and vector "verList". I am passing this one to thread as a function argument
for(int color = 1; color <= 7 ; color++)
{
        srcMesh.reportVertex(color,verList); //all the vertices in srcMesh with the same color index will be stored in verList datastructure(vector)

        std::vector<Vertex *>::iterator vit = verList.begin();
        input->vit = vit;

for(int i = 0; i < 100; i++)
                HANDLE hThread[i] = createThread(0,0,&thread_fun,&input,0,NULL);
        WaitForMultipleObjects(100,hThread,TRUE,INFINITE);
        for(int i = 0; i < 100; i++)
               CloseHandle(hThread[i]);
}
msmoother.computeEnergy();     // compute harmonic energy based on edge weights
}

在 thread_fun 中,我在 msmoother 对象上调用一个方法,以便使用边缘权重以及 dstMesh 更新 msmoother 对象。 dstMesh 与线程功能完美更新。为了在 msmoother 对象上执行 computeEnergy,对象应该返回到主线程或者它的状态应该被持久化。但它将能量返回为“0”。我怎样才能做到这一点?

【问题讨论】:

    标签: c++ multithreading visual-studio-2010 visual-c++


    【解决方案1】:

    内存在线程之间共享,因此它们对共享数据所做的所有修改最终都会变得可见,而无需任何额外的努力(return 或 persist 东西)。

    显然,您的问题是,在尝试使用它们应该准备好的数据之前,您没有等待线程完成。由于您已经有一个线程句柄数组,WaitForMultipleObjects 应该是等待所有线程完成的便捷方式(注意bWaitAll 参数)。请注意,WaitForMultipleObjects 一次不能等待超过 64 个对象,因此如果您有 100 个线程,则需要两次调用。

    【讨论】:

    • 比我快 14 秒...哦,那你为什么移动得这么快。因为我忘了提到 100 个对象的限制,所以支持你的。
    • 实际上我在调用 computeEnergy 方法之前调用了 WaitForMultipleObjects 和 CloseHandle 方法。我更新了代码。
    • @您好,您没有检查错误,并且肯定有是每次等待超过 64 个(或者是 63 个?)对象的错误。
    • @AntonKovalenko 我将 bWaitAll 参数设置为 TRUE。然后,我将线程数减少到 50。我仍然遇到同样的问题
    【解决方案2】:

    如果 computeEnergy() 要求所有线程都已完成,您可以将每个线程的句柄传递给支持等待线程完成的 WaitForMultipleObject。在每个线程中,您可以添加或修改 msmoother 对象中的值(通过指向 thread_fun 的指针传递)。

    msmoother 对象将一直存在,直到线程全部返回,因此传递指向它的指针是可以接受的。

    【讨论】:

    • 实际上我在调用 computeEnergy 方法之前调用了 WaitForMultipleObjects 和 CloseHandle 方法。我更新了代码。根据您的回答,我的理解是从工作线程返回后,该对象将保留在主线程上?但为什么它不是计算能量呢?
    • @Hello 你真的在更新 DataStructure 吗?您在对createThread 的调用中传递了一个指向指针的指针。您可能会意外修改一组不同的内存。
    • 我更新了数据结构和线程函数的代码。请检查一下
    • @您好,是的,因为我怀疑您没有将指针取消引用到指针。所以目前你正在修改未定义的内存。它可能随时崩溃或损坏您的程序。修改HANDLE hThread[i] = createThread(0,0,&amp;thread_fun,&amp;input,0,NULL);这一行,只需将&amp;input替换为input,因为输入已经是一个指针。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    相关资源
    最近更新 更多