【问题标题】:New to threads : problems using std::ref() in thread parameters线程新手:在线程参数中使用 std::ref() 的问题
【发布时间】:2015-11-23 13:41:18
【问题描述】:

我是 C++ 线程的新手,我尝试让多个对象打包在 std::vector 中,异步调用它们的 prepareForRendering(...) 方法。看来我错误地使用了std::ref。这有效:

for (ObjMesh& mesh : this->meshes) {

    // Prepare mesh
    std::thread t(&ObjMesh::prepareForRendering, mesh, pDevice, prepareTextures, prepareVertices, prepareBuffers, filter, addressMode);
    t.join();
}

这不是:

for (ObjMesh& mesh : this->meshes) {

    // Prepare mesh
    std::thread t(&ObjMesh::prepareForRendering, std::ref(mesh), pDevice, prepareTextures, prepareVertices, prepareBuffers, filter, addressMode);
    t.join();
}

编译器抛出:

1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(238): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(238): note: With the following template arguments:
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(238): note: '_Callable=bool (__thiscall ObjMesh::* )(ID3D11Device *,bool,bool,bool,D3D11_FILTER,D3D11_TEXTURE_ADDRESS_MODE)'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(238): note: '_Types={std::reference_wrapper<ObjMesh>, ID3D11Device *, bool, bool, bool, D3D11_FILTER, D3D11_TEXTURE_ADDRESS_MODE}'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(247): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0,1,2,3,4,5,6,7>(std::tuple<bool (__thiscall ObjMesh::* )(ID3D11Device *,bool,bool,bool,D3D11_FILTER,D3D11_TEXTURE_ADDRESS_MODE),std::reference_wrapper<ObjMesh>,ID3D11Device *,bool,bool,bool,D3D11_FILTER,D3D11_TEXTURE_ADDRESS_MODE> &,std::integer_sequence<_Ty,0,1,2,3,4,5,6,7>)' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<bool (__thiscall ObjMesh::* )(ID3D11Device *,bool,bool,bool,D3D11_FILTER,D3D11_TEXTURE_ADDRESS_MODE),std::reference_wrapper<ObjMesh>,ID3D11Device *,bool,bool,bool,D3D11_FILTER,D3D11_TEXTURE_ADDRESS_MODE>,std::default_delete<std::tuple<bool (__thiscall ObjMesh::* )(ID3D11Device *,bool,bool,bool,D3D11_FILTER,D3D11_TEXTURE_ADDRESS_MODE),std::reference_wrapper<ObjMesh>,ID3D11Device *,bool,bool,bool,D3D11_FILTER,D3D11_TEXTURE_ADDRESS_MODE>>>,
1>              _Ty=size_t
1>          ]

我需要确保ObjMesh 实例在线程内通过引用传递。

(我知道我的线程模型没有意义 - 这是一个示例)。 TYVM。

EDIT准备渲染功能。

bool ObjMesh::prepareForRendering(ID3D11Device* pDevice, bool prepareTextures,  bool prepareVertices, bool prepareBuffers, D3D11_FILTER filter, D3D11_TEXTURE_ADDRESS_MODE addressMode);

【问题讨论】:

  • 为什么要用std::ref 代替mesh,它已经是一个参考了?第一个代码所做的是(本质上)mesh.prepareForRendering(pDevice, ...)std::ref 返回的包装器不支持该语义。
  • mesh.prepareForRendering(pDevice, ...) 在第一个 sn-p 中处理 mesh 的副本。我的问题是:我需要 mesh 在线程内作为引用传递。这甚至可能吗?
  • 或者我完全错了,问题是别的什么?
  • 您需要提供prepareForRending的签名。
  • 我认为问题可能是由于 prepForRendering 函数创建 DX11 缓冲区我猜 它的线程本地 并在尝试读取它时给我一个读取访问冲突从主线程。这有意义吗?

标签: c++ multithreading c++11 pass-by-reference


【解决方案1】:

只需将指针传递给绑定:

std::thread t(&ObjMesh::prepareForRendering, &mesh, pDevice, prepareTextures, prepareVertices, prepareBuffers, filter, addressMode);

【讨论】:

  • 我做了,但似乎我的问题在其他地方。确实解决了我的问题标题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多