如何同步对许多对象的访问

viv*_*dos 11 c++ multithreading synchronization boost

我有一个线程池,其中包含一些线程(例如,尽可能多的内核),它们可以处理许多对象,例如数千个对象.通常我会给每个对象一个互斥锁以保护对其内部的访问,在我工作时将其锁定,然后释放它.当两个线程尝试访问同一个对象时,其中一个线程必须等待.

现在我想节省一些资源并且可以扩展,因为可能有数千个对象,并且仍然只有一大堆线程.我正在考虑一个类设计,其中线程具有某种互斥或锁定对象,并在访问对象时将锁分配给对象.这样可以节省资源,因为我只拥有与线程一样多的锁定对象.

现在是编程部分,我想将这个设计转移到代码中,但不知道从哪里开始.我正在使用C++进行编程,并希望尽可能使用Boost类,但是处理这些特殊要求的自编写的类是可以的.我该如何实现?

我的第一个想法是每个线程都有一个boost :: mutex对象,每个对象都有一个最初未设置的boost :: shared_ptr(或NULL).现在,当我想访问该对象时,我通过创建一个scoped_lock对象并将其分配给shared_ptr来锁定它.当shared_ptr已经设置好后,我等待当前的锁定.这个想法听起来像一堆充满竞争条件,所以我有点放弃它.还有另一种方法来完成这个设计吗?一种完全不同的方式?

编辑:上面的描述有点抽象,所以让我添加一个具体的例子.想象一下拥有许多物体的虚拟世界(想想> 100.000).在世界上移动的用户可以在世界中移动并修改对象(例如在怪物处射箭).当只使用一个线程时,我很擅长一个工作队列,其中对象的修改排队.不过,我想要一个更具伸缩性的设计.如果128个核心处理器可用,我想使用全部128个,所以使用这个数量的线程,每个线程都有工作队列.一种解决方案是使用空间分离,例如对区域使用锁定.这可以减少使用的锁的数量,但是如果有一个设计可以节省尽可能多的锁,我会更感兴趣.

Joh*_*ing 4

您可以使用互斥体池,而不是为每个资源分配一个互斥体或每个线程分配一个互斥体。当请求互斥体时,首先检查有问题的对象。如果它已经标记了一个互斥体,则阻止该互斥体。如果没有,则为该对象分配一个互斥体并向其发出信号,将互斥体从池中取出。一旦互斥体被取消信号,则清除插槽并将互斥体返回到池中。

  • @vividos。您需要一个互斥锁来保护您的互斥锁池,但只要有一个可用的互斥锁,从池中获取互斥锁的操作应该相对较快。如果 OP 的目的是对需要锁定一段时间的项目执行长时间操作,那么您希望将这种“长期持有”的锁定仅应用于一个对象。 (2认同)