我是多執行緒的新手,想嘗試用2048*2048的高度圖紋理生成一組頂點。
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;
}
}
}
問題是當我嘗試將執行緒添加到向量時,如果我一一添加它們:
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); }));
然后一切正常運行。
但是如果我使用回圈添加執行緒:
for (int i = 0; i < 4; i) {
threads.push_back(std::thread([&]
{CalculateVertices(vertex_scale, texture_scale, dataSize * i, dataSize * (i 1), data); }));
}
,出現錯誤,它顯示函式“CalculateVertices”中的引數“end”為2560。邏輯上,范圍不應超過2048。
然后我嘗試做一些改變,我只是計算不在引數串列中的“開始”和“結束”:
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); }));
}
,現在超出范圍的問題已經解決了,但是結果還是不對,好像只生成了一半的頂點。
我對多執行緒不熟悉,這是我第一次嘗試使用多執行緒,我想知道問題的原因。根據我的經驗,我只是將代碼一一改成回圈,邏輯應該不會不同。
uj5u.com熱心網友回復:
秘訣是您的惰性自動捕獲參考:
std::thread([&]{ /*...*/ })
這幾乎總是一個壞主意。在這種情況下,您i通過參考捕獲,這意味著當執行緒呼叫 lambda 時,i可能甚至不存在并且肯定不會具有正確的值。
至少,i按價值捕獲。實際上,在這種情況下,您可能可以按值捕獲所有這些東西。
std::thread([=]{ /*...*/ })
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/532704.html
標籤:C 多线程
