Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我做错了什么?(多线程)_C++_C_Multithreading - Fatal编程技术网

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

C++ 我做错了什么?(多线程),c++,c,multithreading,C++,C,Multithreading,简而言之,这就是我正在做的 在我班的cpp文件中,我有: std::vector<std::vector<GLdouble>> ThreadPts[4]; 然后它似乎没有崩溃,会出什么问题 谢谢问题在于,您将相同的dat结构传递给每个线程,作为threadproc的参数 例如,当您启动线程1时,无法保证在主线程开始加载相同的dat结构和线程2的信息之前,它已经读取了dat结构中的信息(依此类推)。事实上,在整个线程的循环中,您一直在直接使用dat结构,因此在线程基本完成

简而言之,这就是我正在做的

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

std::vector<std::vector<GLdouble>> ThreadPts[4];
然后它似乎没有崩溃,会出什么问题


谢谢

问题在于,您将相同的
dat
结构传递给每个线程,作为threadproc的参数

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

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


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

+1,很好的捕获。为了推广相同的规则,当您将一些数据传递给线程时,通常最容易将所有权转移给该线程,因此它属于该线程,并且父线程再也不会接触它(至少在该线程明确表示它已完成并将数据传输回父线程之前)。
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;

}
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);
dat.start = dat.end;
dat.end = Contour[i].UserPoints.size();
dat.whichVector = 3;

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