2011-08-04 9 views
7

Esto podría ser una optimización prematura, o una sobreprotección prematura, pero estoy evitando usar singletons en algunas clases porque me preocupa que en el futuro necesitaré ejecutar mi aplicación como multiproceso, y que el los singletons crearán conflictos y desorden. ¿Los singleton tienen este problema en Ruby, o hay algún tipo de espacio de nombres incorporado para que cuando una clase se refiera al singleton, solo se devuelva el singleton en el mismo hilo?¿Las clases singleton crean problemas en una aplicación de subprocesos múltiples?

Editar: para aclarar estas son clases observables que cuando se actualizan causan que las otras clases que las están viendo se actualicen. No estoy seguro de si esto es seguro o no, pero sé que en este momento estoy pasando estas clases observables alrededor de una tonelada y es un poco molesto. Y parecen clases naturales únicas.

+0

ámbito compartido (singleton o no) puede causa problemas en una aplicación multi-roscado. – R0MANARMY

+1

^eso! El singleton ruby ​​mixin es seguro para hilos en términos de "obtienes la misma instancia en todos los hilos, garantizado". como Michael Kohl ya escribió. Sin embargo, mantener su thread de implementación "single" seguro es su responsabilidad. – paukul

Respuesta

7

Todas las clases que no están escritas para ser seguras para subprocesos causarán problemas en un entorno de múltiples subprocesos, independientemente de si son únicos o no.

El hecho de que su clase sea singleton podría empeorar el problema, ya que se comparte de forma predeterminada. No puede tener una instancia por subproceso.

Si el estado de singleton es de solo lectura e inmutable, no tendrá un problema de seguridad de subprocesos.

Si se modifica el estado compartido, debe asegurarse de que sea seguro para subprocesos.

+1

Inmutable, no soy lo suficientemente específico en este caso. Puede ser una clase que solo expone el acceso de solo lectura a los datos pero modifica su estado interno debajo. – R0MANARMY

+0

+1 para la primera línea. – AShelly

+1

Si modifica su estado interno, entonces no es inmutable. – duffymo

2

Aunque esto parece un caso de YAGNI, la Singleton class sí requiere thread y declara lo siguiente en la documentación:

Klass._instantiate() - regresar `` la instancia’’ o nulo?. Este método de gancho pone un segundo (o n. °) hilo que llama a Klass.instance() en un bucle de espera . El valor devuelto significa la finalización con éxito o la terminación prematura de la primera, o más generalmente, actual "cadena de creación de instancias".

¿Eso ayuda?

6

Aquí hay un ejemplo de cómo hacer una rosca singelton. Debe tratarlo como cualquier otro objeto que tenga estado (@things) y no sea inmutable (solo lectura). Los getters y setters necesitan acceder al estado interno a través de un Mutex (exclusión mutua).

require 'singleton' 

class MyObject 
    include Singleton 

    def initialize 
    @things = [] 
    @mutex = Mutex.new 
    end 

    def add(thing) 
    with_mutex { @things << thing } 
    end 

    def things 
    with_mutex { @things } 
    end 

    def clear 
    with_mutex { @things.clear } 
    end 

    def self.add(thing) 
    instance.add(thing) 
    end 

    def self.things 
    instance.things 
    end 

    def self.clear 
    instance.clear 
    end 

    private 

    def with_mutex 
    @mutex.synchronize { yield } 
    end 
end 

Lectura adicional: http://rubylearning.com/satishtalim/ruby_threads.html

+1

Creo que llamar a Mutex.new en los métodos dará lugar a condiciones de carrera cuando dos hilos podrían comenzar a inicializar al mismo tiempo sobrescribir la variable @mutex. – Zmey

+0

@Zmey Gracias - Arreglé el código para reflejar esto :) – Kris

Cuestiones relacionadas