Concurency:共享相同的内存空间

时间:2015-11-23 15:10:25

标签: c++ multithreading concurrency shared-memory directx-11

在C ++ 11& 14中是否有办法让每个任务共享相同的“内存空间”或其他任何内容?

我的问题:我有一堆3D网格,它们通过(除其他事项外)使用DX11函数创建自己的缓冲区(即顶点缓冲区)来“自行准备”。

我尝试的是为每个对象创建一个线程,以便他们可以在自己的线程中“自己准备”。我加入后尝试从主线程中读取线程的缓冲区内存会给我一个读访问权限。

我有感觉(我不是专家)说缓冲区是他们的线程的本地,因此我不能再读它们了 - 甚至它们都被破坏了@ thread join。

我的观点是否正确&这个问题有解决方法吗?

我发布的是图片而不是代码。

schema

打破:

// Update shader interface
pDeviceContext->UpdateSubresource(this->meshShaderInterfaceBuffer, 0, nullptr, &(this->meshShaderInterface), 0, 0);

enter image description here

错误代码:Exception thrown at 0x759FD09C (kernel32.dll) in dxmed.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC.

编辑根据要求,一些代码摘录。

// I create an ObjModel on the heap
// At this point, ObjModel populates itself with ObjMesh's (model parts)
ObjModel test = new ObjModel("media/models/some_model.obj");

// I call the prepare for rendering method on parent ObjModel
// To make my model drawable. g_d3dDevice is part of the DX11
// context variables. prepareForRendering() definition being:
//    bool prepareForRendering(
//        ID3D11Device* pDevice,
//        bool prepareTextures = true,
//        bool prepareVertices = true,
//        bool prepareBuffers = true,
//        D3D11_FILTER filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR,
//        D3D11_TEXTURE_ADDRESS_MODE addressMode = D3D11_TEXTURE_ADDRESS_CLAMP);
if (!test->prepareForRendering(g_d3dDevice)) return false;

// The prepare for rendering func calls an evenly named func
// on all it's ObjMesh's. This part is causing problems
// apparently when trying to thread it. Code below attempting
// to thread it - inside ObjModel::prepareForRendering(...)
std::vector<std::thread*> pthreads;
for (ObjMesh& mesh : this->meshes) {
    std::thread* t = new std::thread(&ObjMesh::prepareForRendering, &mesh, pDevice, prepareTextures, prepareVertices, prepareBuffers, filter, addressMode);
    pthreads.push_back(t);
}

for (std::thread* t : pthreads) {
    if (t->joinable()) t->join();
}

// After that, I am good to draw() my model. Inside a Render() func.
// Which calls again the draw() func of all it's ObjMesh's
//    void ObjModel::draw(ID3D11DeviceContext* pDeviceContext, D3D11_PRIMITIVE_TOPOLOGY topology) const {
//      if (this->meshes.size() == 0) {
//    #ifdef _DEBUG
//          std::cerr << "Model hasn't any meshes to draw!" << std::endl;
//          MessageBox(nullptr, std::to_string(this->meshes.size()).c_str(), "wtf?", MB_OK);
//    #endif
//      }
//      else {
//          for (const ObjMesh& mesh : this->meshes) {
//              mesh.draw(pDeviceContext, topology);
//          }
//      }
//    }
test->draw(g_d3dDeviceContext);

// Finally, mesh draws itself. Code breaks at ObjMesh trying
// to access it's own buffers (created in the threaded prepareForRendering())

void ObjMesh::draw(ID3D11DeviceContext* pDeviceContext, D3D11_PRIMITIVE_TOPOLOGY topology) const {

    // Whole bunch of stuff...
    // when suddenly...

    // Update shader interface
    pDeviceContext->UpdateSubresource(this->meshShaderInterfaceBuffer, 0, nullptr, &(this->meshShaderInterface), 0, 0);

    // (╯°□°)╯︵ ┻━┻ a wild Access violation reading location 0x12345678 appears ;(

    // Draw
    pDeviceContext->Draw(vertex_data.size(), 0);

    return;
}

任何提示都表示赞赏。

1 个答案:

答案 0 :(得分:0)

问题解决了:我的一些缓冲区甚至没有机会被创建,因为我在缓冲区创建部分之前的某些情况下正在中止prepareForRendering函数。案例是:尝试从文件(CreateWICTextureFromFileEx https://msdn.microsoft.com/en-us/library/windows/desktop/ff476904%28v=vs.85%29.aspx)创建纹理资源。

我的纹理创建(全部)意外失败,因为他们需要的COM接口并未设置为在多线程模式下工作(请参阅 - https://msdn.microsoft.com/en-us/library/windows/desktop/ms695279%28v=vs.85%29.aspx CoinitializeEx)。

这让我重新开始,因为我无法使用多线程COM接口初始化Ribbon Framework ...... :(

有关此问题的专家吗?

编辑解决:CoInitialize可以多次调用(使用CoUninitialize)。