简体   繁体   English

如何使用共享数据同步线程С++

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

I am writing a simple minecraft clone and I need help.我正在编写一个简单的我的世界克隆,我需要帮助。 I have a "Chunk" class that implements the "calculateMesh" and "createChunk" methods, the second method fills the chunk blocks field with a specific block type, and then the "calculateMesh" method adds the required edges (if the block is not locked or the block is not transparent).我有一个实现“calculateMesh”和“createChunk”方法的“Chunk”class,第二种方法用特定的块类型填充块块字段,然后“calculateMesh”方法添加所需的边(如果块不是锁定或块不透明)。 Also, chunks can get a block of another chunk through the "World" class, which stores pointers to all chunks.此外,块可以通过“世界”class 获得另一个块的块,该块存储指向所有块的指针。 To form the correct mesh, the createChunk methods for all chunks must complete.要形成正确的网格,必须完成所有块的 createChunk 方法。 Both operations are heavy and they block the main thread if a new chunk was added.这两个操作都很繁重,如果添加了新块,它们会阻塞主线程。 So, I thought that I need to add a thread pool to my project.所以,我认为我需要在我的项目中添加一个线程池。 I did it.我做的。 But I don't know how to synchronize the threads to avoid errors when one chunk is trying to get a block of another unfinished chun.但是当一个块试图获取另一个未完成的块的块时,我不知道如何同步线程以避免错误。 I think all blocks should wait for the createChunk method to complete and then create the mesh.我认为所有块都应该等待 createChunk 方法完成,然后创建网格。 How should I do it?我该怎么做? Maybe use a priority queue in my thread pool?也许在我的线程池中使用优先级队列? (Sorry for my English:)) (对不起我的英语不好:))

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

You can use std::async to achieve that i think.您可以使用std::async来实现我的想法。 You should bind the function to std::async object which will call it asynchronously and will return future object.您应该将 function 绑定到std::async object,它将异步调用它并返回未来的 object。 When you get the future return value, it will be attached into the main thread.当你得到未来的返回值时,它会被附加到主线程中。 Here is example usage:这是示例用法:

#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