我正在开发一个在Windows和Linux上使用c ++的模拟项目。
模拟中将有数千个对象(可能是3000-5000)。计划让多个线程对对象执行操作,以便充分利用多核机器,例如一个线程处理对象的移动和位置,一个(或多个)处理对象之间的交互,一个处理创建新的对象。
但是,这需要线程之间的同步以确保它正常工作。所以我认为每个对象应该包含一个(pthread mutex / CRITICAL_SECTION),具体取决于平台,然后每个线程可以锁定它当前正在处理的对象。因为有很多对象争用应该很少,所以它应该很快。
所以我的第一个问题是3000-5000 pthread互斥或windows关键部分太多了?我不知道这两个系统有什么限制。或者有更好的方法来实现这一目标吗?
我的第二个问题是关于保存对象的数据结构。因为可以创建对象并“死”,所以我觉得最好的方法是存储工作线程可以迭代的活动对象的“列表”。但是,c ++列表不是线程安全的。如果我的一个线程删除了一个对象,我需要将它与另一个在列表上执行“next()”的对象同步。此外,我需要确保“下一个”对象在将迭代器移动到它之前被锁定,所以我需要对整个集合进行某种全局锁定,在插入/删除对象之前我必须获得这种锁定。移动到线程上的下一个对象。
这似乎很痛苦,而且可能很慢。有更好的方法吗?
答案 0 :(得分:3)
特别是在您的Windows平台上,您可以查看Slim Reader/Writer (SRW) Locks - 这将允许多个并发读者。
答案 1 :(得分:3)
看看无锁的收藏品。我相信英特尔的Threading Building Blocks(开源)有一些。
答案 2 :(得分:1)
为什么不让每个线程在不同的对象上工作,而不是让线程对对象执行不同的操作?听起来你正在做粒子碰撞。我参与了一个与此类似的项目,尽管我没有线程化。但是,如果您可以将对象分组为“空格”,则每个线程可以在自己的空间中工作,并将对象从一个空间传递到另一个空间。如果你有1个线程进行位置跟踪,1个线程进行碰撞计算,那么你将会破坏你的性能,因为这些计算是非常紧密耦合的。当一个线程不直接依赖于其他线程时,线程(通常)只是好的。
答案 3 :(得分:0)
您可以在Linux上创建pthread_mutex_t
的数量没有固有的限制 - 它们不必在任何地方集中注册。解锁的互斥锁不会占用用于存储pthread_mutex_t
的字节以外的任何资源。
如果您要锁定每个单独的对象,请注意锁定顺序死锁。您需要在对象上定义严格的顺序,并确保它们始终按该顺序锁定。