如何对 std::vector 元素中的对象使用 shared_mutex
How to use shared_mutex for objects in std::vector elements
问题
我目前正在开发一款游戏。在这个游戏中,某种类型的"game objects"被存储在一个std::vector中。这些对象的更新(游戏)代码在一个线程上执行,而渲染则由主线程处理。
这些 "game objects" 的向量通过引用传递给处理它们的更新代码的线程,以便在线程之间共享数据。因此,需要某种形式的线程安全,以防止呈现代码尝试访问正在被更新代码修改的内存(这会导致崩溃)。
理想情况下,我想使用 shared_mutex 作为存储在所述向量中的这些 "game objects" 的一部分。但是,这不会编译并导致错误。我的理解是,这是因为无法复制互斥锁。
有没有解决这个问题的高效、安全且 "not a nightmare to work with" 的方法?
我看到的唯一可行的解决方案是防止每种特定类型的对象同时更新和呈现。但是,这会在某种程度上抵消多线程的好处。我估计超过 80% 的游戏将处理一种单一类型的对象。
提供以下上下文的基本伪代码:
main(){
std::vector<Enemies> enemies;
std::thread(update_thread, std::ref(enemies), ... , ...);
while(true){
render_player();
render_enemies();
render_physics();
flip_to_display()
}
};
update_thread(std::vector<Enemies> &enemies, ... , ...){
while(true){
update_player();
update_enemies();
update_physics();
}
};
render_enemies(){
for(all enemies)
enemy.render();
}
update_enemies(){
for(all enemies)
enemy.update();
}
class Enemies{
//Would be nice to have the below, but afaik, not possible
std::shared_mutex mutex;
update(){
std::shared_lock<std::shared_mutex> lock(mutex);
//Write and Access data from enemy
}
render(){
std::shared_lock<std::shared_mutex> lock_shared(mutex);
//Only Access some data from enemy and draw it
}
}
注意:
我正在使用 visual studio 2015,所以我只能使用 C++14(ish) 兼容的功能。
根据评论中提供的答案,我认为我最好的选择是找到一个更有创意的解决方案来完全回避这个问题。在这种情况下,我可能会提前处理并将结果写入缓冲区。这样渲染和处理应该通过设计避免任何冲突,从而避免需要锁定条件。
如果我记得,这很可能会成为公认的解决方案(因为按钮不能按下 2 天)。
问题
我目前正在开发一款游戏。在这个游戏中,某种类型的"game objects"被存储在一个std::vector中。这些对象的更新(游戏)代码在一个线程上执行,而渲染则由主线程处理。
这些 "game objects" 的向量通过引用传递给处理它们的更新代码的线程,以便在线程之间共享数据。因此,需要某种形式的线程安全,以防止呈现代码尝试访问正在被更新代码修改的内存(这会导致崩溃)。
理想情况下,我想使用 shared_mutex 作为存储在所述向量中的这些 "game objects" 的一部分。但是,这不会编译并导致错误。我的理解是,这是因为无法复制互斥锁。
有没有解决这个问题的高效、安全且 "not a nightmare to work with" 的方法?
我看到的唯一可行的解决方案是防止每种特定类型的对象同时更新和呈现。但是,这会在某种程度上抵消多线程的好处。我估计超过 80% 的游戏将处理一种单一类型的对象。
提供以下上下文的基本伪代码:
main(){
std::vector<Enemies> enemies;
std::thread(update_thread, std::ref(enemies), ... , ...);
while(true){
render_player();
render_enemies();
render_physics();
flip_to_display()
}
};
update_thread(std::vector<Enemies> &enemies, ... , ...){
while(true){
update_player();
update_enemies();
update_physics();
}
};
render_enemies(){
for(all enemies)
enemy.render();
}
update_enemies(){
for(all enemies)
enemy.update();
}
class Enemies{
//Would be nice to have the below, but afaik, not possible
std::shared_mutex mutex;
update(){
std::shared_lock<std::shared_mutex> lock(mutex);
//Write and Access data from enemy
}
render(){
std::shared_lock<std::shared_mutex> lock_shared(mutex);
//Only Access some data from enemy and draw it
}
}
注意: 我正在使用 visual studio 2015,所以我只能使用 C++14(ish) 兼容的功能。
根据评论中提供的答案,我认为我最好的选择是找到一个更有创意的解决方案来完全回避这个问题。在这种情况下,我可能会提前处理并将结果写入缓冲区。这样渲染和处理应该通过设计避免任何冲突,从而避免需要锁定条件。
如果我记得,这很可能会成为公认的解决方案(因为按钮不能按下 2 天)。