簡體   English   中英

我究竟做錯了什么? (多線程)

[英]What am I doing wrong? (multithreading)

這就是我正在做的事情。

在我班級的cpp文件中,我有:

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

線程proc看起來像這樣:

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看起來像這樣:

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

    }
}

調用線程的代碼如下所示:

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.如果我刪除:

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

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

然后它似乎沒有崩潰,可能是什么錯?

謝謝

問題是你將每個線程傳遞的相同dat結構作為threadproc的參數傳遞。

例如,當您啟動線程1時,無法保證在主線程開始使用線程2的信息(依此類推)加載相同的dat結構之前,它將讀取dat結構中的信息。 事實上,你經常在整個線程的循環中直接使用該dat結構,因此在線程基本完成所有工作之前,線程將不會完成傳遞給它的結構。

另請注意, SetCubicBezier()中的currentvector是對data->whichVector的引用,它指的是線程中完全相同的位置。 因此, SetCubicBezier()將在不同的線程中對同一對象執行push_back()調用。

有一個非常簡單的修復:您應該使用四個單獨的SHAPETHREADDATA實例 - 一個用於初始化每個線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM