并发性:共享相同的内存 space
Concurency : sharing same memory space
C++11&|14 中有没有一种方法可以让每个任务共享相同的 "memory space" 或其他名称并发?
我的问题:我有一堆 3D 网格,它们 "preparing themselves" 通过(除其他外)使用 DX11 函数创建它们自己的缓冲区(即顶点缓冲区)。
我尝试为每个对象创建一个线程,以便它们可以 "prepare themselves" 在自己的线程中。在我加入主线程后尝试从主线程读取线程的缓冲区内存给了我读取访问冲突。
我有一种感觉(我不是专家)说缓冲区在它们的线程中是本地的,因此我不能再读取它们了——甚至它们在线程连接时被破坏了。
我的观点是否正确?是否有解决此问题的方法?
我发布的是图片而不是代码。
打破:
// 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;
}
感谢任何提示。
问题已解决:我的一些缓冲区甚至没有机会创建,因为在某些情况下我在缓冲区创建部分之前中止了 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
)。
C++11&|14 中有没有一种方法可以让每个任务共享相同的 "memory space" 或其他名称并发?
我的问题:我有一堆 3D 网格,它们 "preparing themselves" 通过(除其他外)使用 DX11 函数创建它们自己的缓冲区(即顶点缓冲区)。
我尝试为每个对象创建一个线程,以便它们可以 "prepare themselves" 在自己的线程中。在我加入主线程后尝试从主线程读取线程的缓冲区内存给了我读取访问冲突。
我有一种感觉(我不是专家)说缓冲区在它们的线程中是本地的,因此我不能再读取它们了——甚至它们在线程连接时被破坏了。
我的观点是否正确?是否有解决此问题的方法?
我发布的是图片而不是代码。
打破:
// 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;
}
感谢任何提示。
问题已解决:我的一些缓冲区甚至没有机会创建,因为在某些情况下我在缓冲区创建部分之前中止了 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
)。