Home > database >  why the result is different add thread by loop
why the result is different add thread by loop

Time:11-11

I am the novice of multithreading, and I want to try to use the 2048*2048 height map texture to generate a set of vertices.

void HeightMap::CalculateVertices(Vector3 vertex_scale, Vector2 texture_scale, int start, int end, GLubyte* data) {
    for (unsigned int z = start; z < end;   z) {
        for (unsigned int x = 0; x < width;   x) {
            unsigned int offset = z * height   x;
            vertices[offset] = Vector3(x, data[offset], z) * vertex_scale;
            textureCoords[offset] = Vector2(x, z) * texture_scale;
        }
    }
}

The problem is when I try to add thread to vector, if I add them one by one:

    threads.push_back(std::thread([&]
        {CalculateVertices(vertex_scale, texture_scale, 0, dataSize, data); }));
    threads.push_back(std::thread([&]
        {CalculateVertices(vertex_scale, texture_scale, dataSize, dataSize * 2, data); }));
    threads.push_back(std::thread([&]
        {CalculateVertices(vertex_scale, texture_scale, dataSize * 2, dataSize * 3, data); }));
    threads.push_back(std::thread([&]
        {CalculateVertices(vertex_scale, texture_scale, dataSize * 3, dataSize * 4, data); }));

Then everything run properly.

But if I use loop to add thread:

    for (int i = 0; i < 4;   i) {
        threads.push_back(std::thread([&]
            {CalculateVertices(vertex_scale, texture_scale, dataSize * i, dataSize * (i   1), data); }));
    }

, the error occured, it shows the parameter "end" in the function "CalculateVertices" is 2560. Logically, the range should not exceed 2048.

Then I try to do some change, I just calculate the "start" and "end" not in the parameter list:

    for (int i = 0; i < 4;   i) {
        int start = dataSize * i;
        int end = dataSize * (i   1);
        threads.push_back(std::thread([&]
            {CalculateVertices(vertex_scale, texture_scale, dataSize * i, dataSize * (i   1), data); }));
    }

, now the out of range problem is fixed, but the result still wrong, it seems only generate half of the vertices.

I am not familiar to multithreading, and this is my first attempt to use multithreading, I want to know the reason of the problem. According to my experience, I just change one-by-one code to loop, the logic should not be different.

CodePudding user response:

The secret is your lazy auto-capture-by reference:

std::thread([&]{ /*...*/ })

This is almost always a bad idea. In this case, you are capturing i by reference, which means when the thread invokes the lambda, i might not even exist and will certainly not have the correct value.

At the very least, capture i by value. In fact, you can probably capture all this stuff by value in this case.

std::thread([=]{ /*...*/ })
  • Related