【问题标题】:Concurency : sharing same memory space并发:共享相同的内存空间
【发布时间】:2015-11-23 15:10:25
【问题描述】:

在 C++11&|14 中是否有办法让每个任务共享相同的“内存空间”或任何所谓的并发?

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

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

我有一种感觉(我不是专家)说缓冲区是他们线程的本地缓冲区,因此我无法再读取它们 - 甚至它们在线程加入时被破坏了。

我的观点是否正确?是否有解决此问题的方法?

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

休息:

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

错误代码: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;
}

任何提示表示赞赏。

【问题讨论】:

  • 如果它们是同一进程中的线程,那么您应该能够在另一个线程中看到来自一个线程的数据 - 尽管您应该注意线程安全问题。
  • 我的读取访问冲突可能来自哪里?我只是在所有线程都加入后才尝试阅读,并且没有线程尝试读取另一个线程。
  • 您要求我们调试我们看不到的代码。你能创建最小的、独立的代码来重现问题吗?
  • @DragonRock:这完全被打破了。您必须在 C++17 中等待 atomic_shared_ptr...
  • @KerrekSB 我不知道,谢谢你的精确

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


【解决方案1】:

问题已解决:我的一些缓冲区甚至没有机会被创建,因为在某些情况下我在缓冲区创建部分之前中止了prepareForRendering 函数。案例:尝试从文件(CreateWICTextureFromFileExhttps://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 框架...:(

有这方面的专家吗?

EDIT 已解决:CoInitialize 可以多次调用(使用 CoUninitialize)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 2012-03-02
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 1970-01-01
    相关资源
    最近更新 更多