Tengo un grupo de subprocesos con algunos subprocesos (por ejemplo, tantos como núcleos) que funcionan en muchos objetos, digamos miles de objetos. Normalmente le daría a cada objeto un mutex para proteger el acceso a sus partes internas, lo bloquearé cuando estoy trabajando y luego lo liberaré. Cuando dos hilos intentan acceder al mismo objeto, uno de los hilos tiene que esperar.Cómo sincronizar el acceso a muchos objetos
Ahora quiero ahorrar algunos recursos y sea escalable, ya que puede haber miles de objetos, y aún así sólo una mano llena de hilos. Estoy pensando en un diseño de clase donde el subproceso tiene algún tipo de objeto mutex o de bloqueo, y asigna el bloqueo al objeto cuando se debe acceder al objeto. Esto ahorraría recursos, ya que solo tengo tantos objetos de bloqueo como thread.
Ahora viene la parte de programación, donde quiero transferir este diseño a código, pero no sé exactamente por dónde empezar. Estoy programando en C++ y quiero usar clases de Boost siempre que sea posible, pero las clases auto escritas que manejan estos requisitos especiales están bien. ¿Cómo implementaría esto?
Mi primera idea fue tener un :: objeto mutex boost por hilo, y cada objeto tiene un boost :: shared_ptr que inicialmente está desarmado (o NULL). Ahora cuando quiero acceder al objeto, lo bloqueo creando un objeto scoped_lock y lo asigno a shared_ptr. Cuando el shared_ptr ya está configurado, espero en el bloqueo actual. Esta idea suena como un montón de condiciones de carrera, así que de alguna manera la abandoné. ¿Hay alguna otra forma de lograr este diseño? Una forma completamente diferente?
Editar: La descripción anterior es un poco abstracta, así que permítanme agregar un ejemplo específico. Imagine un mundo virtual con muchos objetos (piense> 100.000). Los usuarios que se muevan en el mundo podrían moverse por el mundo y modificar objetos (por ejemplo, disparar flechas contra monstruos). Cuando solo uso un hilo, estoy bien con una cola de trabajo donde las modificaciones a los objetos están en cola. Sin embargo, quiero un diseño más escalable. Si hay 128 procesadores centrales disponibles, quiero usar los 128, así que use esa cantidad de hilos, cada uno con colas de trabajos. Una solución sería usar separación espacial, p. usa un candado para un área Esto podría reducir el número de bloqueos utilizados, pero estoy más interesado si hay un diseño que ahorre la mayor cantidad de bloqueos posible.
Eso parece que resolverá el problema. Como los objetos tienen un identificador único, el grupo de exclusión mutua tiene una forma de identificar los objetos. Lo estoy probando. ¡Gracias! – vividos
¿No acaba de mover el problema un nivel? Ahora necesitamos un mutex en el objeto para asegurarnos de que es seguro asignar un mutex al objeto. – stonemetal
No, solo necesita un mutex para proteger su conjunto de mutex (un mapa de id de objeto para mutexes en uso). – vividos