簡體   English   中英

如何使用共享數據同步線程С++

[英]How to synchronize threads with shared data С++

我正在編寫一個簡單的我的世界克隆,我需要幫助。 我有一個實現“calculateMesh”和“createChunk”方法的“Chunk”class,第二種方法用特定的塊類型填充塊塊字段,然后“calculateMesh”方法添加所需的邊(如果塊不是鎖定或塊不透明)。 此外,塊可以通過“世界”class 獲得另一個塊的塊,該塊存儲指向所有塊的指針。 要形成正確的網格,必須完成所有塊的 createChunk 方法。 這兩個操作都很繁重,如果添加了新塊,它們會阻塞主線程。 所以,我認為我需要在我的項目中添加一個線程池。 我做的。 但是當一個塊試圖獲取另一個未完成的塊的塊時,我不知道如何同步線程以避免錯誤。 我認為所有塊都應該等待 createChunk 方法完成,然后創建網格。 我該怎么做? 也許在我的線程池中使用優先級隊列? (對不起我的英語不好:))

void Chunk::createChunk() {
    float heightP = 0.0;

    blocks = new Block[CHUNK_VOLUME];

    for (int x = 0; x < CHUNK_X; x++) {
        for (int z = 0; z < CHUNK_Z; z++) {
            glm::vec3 worldPos = toWorldPosition(glm::vec3(x, 1.0f, z));

            heightP = perlin->noise(worldPos.x * 0.03f, worldPos.y * 0.8f, worldPos.z * 0.03f);

            for (int y = 0; y < CHUNK_Y; y++) {

                BlockType blocktype = StoneBlock;

                if (y > heightP * CHUNK_Y * 0.2f) {
                    blocktype = AirBlock;
                }

                addBlock(x, y, z, blocktype);
            }
        }
    }

    chunkReady = true;
}

void Chunk::calculateMesh() {

    if (hasMesh) {
        return;
    }

    vertices.clear();

    for (int x = 0; x < CHUNK_X; x++) {
        for (int z = 0; z < CHUNK_Z; z++) {
            for (int y = 0; y < CHUNK_Y; y++) {
                if (GetBlock(x, y, z).getBlockType() == StoneBlock) {
                    tryAddFace(x, y, z, BackFace);
                    tryAddFace(x, y, z, LeftFace);
                    tryAddFace(x, y, z, RightFace);
                    tryAddFace(x, y, z, FrontFace);
                    tryAddFace(x, y, z, TopFace);
                    tryAddFace(x, y, z, BottomFace);
                }
            }
        }
    }

    hasMesh = true;
}

Block& Chunk::GetBlock(int x, int y, int z) {
    if (outOfBounds(x, y, z)) {
        glm::vec3 pos = toWorldPosition({ x, y, z });
        return world->GetBlock(pos.x, pos.y, pos.z);
    }

    return blocks[getBlockIndex(x, y, z)];
}

您可以使用std::async來實現我的想法。 您應該將 function 綁定到std::async object,它將異步調用它並返回未來的 object。 當你得到未來的返回值時,它會被附加到主線程中。 這是示例用法:

#include <iostream>
#include <functional>
#include <future>

void foo()
{
    std::cout << "Hello async" << std::endl;  
}

int bar()
{
    return 15; // Your return type and value...
}

int main()
{
   std::future<void> f1 = std::async(std::bind(foo));
   std::future<int> f2 = std::async(std::bind(bar));
   
   f1.get();
   std::cout << f2.get() << std::endl;
   return 0;
}

暫無
暫無

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

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