我究竟做错了什么? (多线程) [英] What am I doing wrong? (multithreading)

查看:116
本文介绍了我究竟做错了什么? (多线程)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我简单地说我做的事情。

Here s what I'm doing in a nutshell.

在我班上的cpp文件我有:

In my class's cpp file I have:

std::vector<std::vector<GLdouble>> ThreadPts[4];

线程PROC看起来是这样的:

The thread proc looks like this:

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看起来是这样的:

SetCubicBezier looks like this:

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

    }
}

在code调用线程看起来是这样的:

The code that calls the threads looks like this:

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

}

是不是有什么问题呢?
我希望它填补ThreadPts [4]; ...永远不应该有任何冲突,我把它设置方式。我通常在得到错误的写作......最后一个线程在那里DAT-> whichvector = 3。如果我删除的:

Is there something wrong with this? I'd expect it to fill ThreadPts[4]; ... There should never be any conflicts the way I have it set up. I usually get error writing at... on the last thread where dat->whichvector = 3. If I remove:

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

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

然后,它似乎并没有崩溃,这可能是错的?

Then it does not seem to crash, what could be wrong?

感谢

推荐答案

的问题是,你传递同一个 DAT 结构,每个线程作为参数传递给ThreadProc的。

The problem is that you're passing the same dat structure to each thread as the argument to the threadproc.

例如,当您启动线程1,有没有保证,这将有你的主线程之前,请阅读 DAT 结构的信息开始加载同一通过信息线程2(依此类推),DAT 结构。事实上,你经常直接使用 DAT 整个线程的回路结构,使该线程将不会传递给它,直到线程结构完成基本完成其所有的工作。

For example, When you start thread 1, there's no guarantee that it will have read the information in the dat structure before your main thread starts loading that same dat structure with the information for thread 2 (and so on). In fact, you're constantly directly using that dat structure throughout the thread's loop, so the thread won't be finished with the structure passed to it until the thread is basically done with all its work.

另外请注意, currentvector SetCubicBezier()数据 - &GT参考; whichVector ,这指的是完全一样的位置在一个线程。因此, SetCubicBezier()将要执行的push_back()调用,因为这个单独的线程在同一对象上。

Also note that currentvector in SetCubicBezier() is a reference to data->whichVector, which is referring to the exact same location in a threads. So SetCubicBezier() will be performing push_back() calls on the same object in separate threads because of this.

有一个非常简单的修复。您应该使用四个独立的 SHAPETHREADDATA 实例 - 一个用来初始化每个线程

There's a very simple fix: you should use four separate SHAPETHREADDATA instances - one to initialize each thread.

这篇关于我究竟做错了什么? (多线程)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆