首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我做错了什么?(多线程)

我做错了什么?(多线程)
EN

Stack Overflow用户
提问于 2010-07-07 04:55:19
回答 1查看 260关注 0票数 3

以下是我要做的简单介绍。

在我的类的cpp文件中,我有:

代码语言:javascript
复制
std::vector<std::vector<GLdouble>> ThreadPts[4];

线程proc如下所示:

代码语言:javascript
复制
unsigned __stdcall BezierThreadProc(void *arg)
{
    SHAPETHREADDATA *data = (SHAPETHREADDATA *) arg;

    OGLSHAPE *obj = reinterpret_cast<OGLSHAPE*>(data->objectptr);
    for(unsigned int i = data->start; i < data->end - 1; ++i)
    {


        obj->SetCubicBezier(
            obj->Contour[data->contournum].UserPoints[i],
            obj->Contour[data->contournum].UserPoints[i + 1],
            data->whichVector);

    }

    _endthreadex( 0 );
    return 0;

}

SetCubicBezier看起来像这样:

代码语言:javascript
复制
void OGLSHAPE::SetCubicBezier(USERFPOINT &a,USERFPOINT &b, int &currentvector )
{
    std::vector<GLdouble> temp;
    if(a.RightHandle.x == a.UserPoint.x && a.RightHandle.y == a.UserPoint.y 
        && b.LeftHandle.x == b.UserPoint.x && b.LeftHandle.y == b.UserPoint.y )
    {
        temp.clear();
        temp.push_back((GLdouble)a.UserPoint.x);
        temp.push_back((GLdouble)a.UserPoint.y);

        ThreadPts[currentvector].push_back(temp);
        temp.clear();
        temp.push_back((GLdouble)b.UserPoint.x);
        temp.push_back((GLdouble)b.UserPoint.y);


        ThreadPts[currentvector].push_back(temp);

    }
}

调用线程的代码如下所示:

代码语言:javascript
复制
for(int i = 0; i < Contour.size(); ++i)
{
    Contour[i].DrawingPoints.clear();

 if(Contour[i].UserPoints.size() < 2)
 {
     break;
 }

HANDLE hThread[4];
SHAPETHREADDATA dat;
dat.objectptr = (void*)this;
dat.start = 0;
dat.end = floor((Contour[i].UserPoints.size() - 1) * 0.25);
dat.whichVector = 0;
dat.contournum = i;



hThread[0] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);

dat.start = dat.end;
dat.end = floor((Contour[i].UserPoints.size() - 1) * 0.5);
dat.whichVector = 1;

hThread[1] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);

dat.start = dat.end;
dat.end = floor((Contour[i].UserPoints.size() - 1) * 0.75);
dat.whichVector = 2;

hThread[2] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);

dat.start = dat.end;
dat.end = Contour[i].UserPoints.size();
dat.whichVector = 3;

hThread[3] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);

WaitForMultipleObjects(4,hThread,true,INFINITE);

}

这有什么问题吗?我希望它能填满ThreadPts4;按照我设置的方式,应该不会有任何冲突。我通常会在写的时候出错...在最后一个线程上,其中dat->whichvector = 3。如果我删除:

代码语言:javascript
复制
dat.start = dat.end;
dat.end = Contour[i].UserPoints.size();
dat.whichVector = 3;

hThread[3] = (HANDLE)_beginthreadex(NULL,0,&BezierThreadProc,&dat,0,0);

那么它似乎没有崩溃,会出什么问题呢?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-07-07 05:10:16

问题是您将相同的dat结构作为参数传递给每个线程。

例如,当您启动线程1时,不能保证在主线程开始使用线程2的信息加载相同的dat结构之前,它已经读取了dat结构中的信息(以此类推)。实际上,您在整个线程循环中经常直接使用dat结构,因此直到线程基本上完成了所有工作之后,它才会完成传递给它的结构。

还要注意,SetCubicBezier()中的currentvector是对data->whichVector的引用,后者引用的是线程中完全相同的位置。因此,SetCubicBezier()将在不同的线程中对同一对象执行push_back()调用。

有一个非常简单的解决方法:您应该使用四个独立的SHAPETHREADDATA实例-每个线程一个实例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3190158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档