2010-02-27 23 views
8

primera:dos preguntas relacionadas con Rubí roscas

  • ¿Cómo puedo crear un hilo que no se inicia away.If derecho utilizo initialize sin un bloque de excepción se levantó.

  • ¿cómo puedo subclase hilo, para que pueda agregar algunos atributos personalizados, pero mantener la misma funcionalidad que la clase de hilo base? También me gustaría no tener que usar el método initialize(&block) para esto.

Para ilustrar mejor este:

Por primera pregunta: ¿

x = Thread.new 
x.run = { 
    # this should happen inside the thread 
} 
x.start # i want to manually start the thread 

Por segundo:

x = MyThread.new 
x.my_attribute = some_value 
x.run = { 
    # this should happen when the thread runs 
} 
x.start 

Busco algo similar a esto. Espero que puedas ayudar.

+3

por qué no puedes "sólo" reemplazar '' x.start' con x = Thread.new {etc} '? –

Respuesta

11

Pregunta 1

examinar la fuente de resonancia magnética 1.8.7 reveló ninguna manera obvia para iniciar un hilo en el estado de la "parado".

Lo que puedes hacer es tener el bloque de hilos en un mutex bloqueado, luego desbloquea el mutex cuando quieras que el hilo vaya.

#!/usr/bin/ruby1.8 

go = Mutex.new 
go.lock 
t = Thread.new do 
    puts "Thread waiting to go" 
    go.lock 
    puts "Thread going" 
end 
puts "Telling the thread to go" 
go.unlock 
puts "Waiting for the thread to complete" 
t.join 

# => Thread waiting to go 
# => Telling the thread to go 
# => Thread going 
# => Waiting for the thread to complete 

Pregunta 2 (tipo de)

Did usted sabe que puede pasar argumentos a su hilo? Cualquier cosa pasó a Thread.new se pasa a través de bloques como argumentos:

#!/usr/bin/ruby1.8 

t = Thread.new(1, 2, 3) do |a, b, c| 
    puts "Thread arguments: #{[a, b, c].inspect}" 
    # => Thread arguments: [1, 2, 3] 
end 

También hay "variables locales hilo," una tienda de clave/valor para cada subproceso. Use Thread#[]= para establecer valores, y Thread#[] para recuperarlos. Puede usar cadenas o símbolos como claves.

#!/usr/bin/ruby1.8 

go = Mutex.new 
go.lock 
t = Thread.new(1, 2, 3) do |a, b, c| 
    go.lock 
    p Thread.current[:foo] # => "Foo!" 
end 
t[:foo] = "Foo!" 
go.unlock 
t.join 

Pregunta 2, realmente

Usted puede hacer lo que quiere hacer. Es mucho trabajo, especialmente cuando la forma habitual de manejar los hilos es muy simple. Vas a tener que sopesar los pros y los contras:

#!/usr/bin/ruby1.8 

require 'forwardable' 

class MyThread 

    extend Forwardable 

    def_delegator :@thread, :join 
    def_delegator :@thread, :[]= 
    def_delegator :@thread, :[] 

    def initialize 
    @go = Mutex.new 
    @go.lock 
    @thread = Thread.new do 
     @go.lock 
     @stufftodo.call 
    end 
    end 

    def run(&block) 
    @stufftodo = block 
    @go.unlock 
    @thread.join 
    end 

end 

t = MyThread.new 
t[:foo] = "Foo!" 
t.run do 
    puts Thread.current[:foo] 
end 
t.join 

# => "Foo!" 
+0

Gracias por tomarse el tiempo para escribir esta respuesta detallada. Fui con variables de subprocesos, usando el método 'Thread.current'. Tu respuesta fue muy interesante. ¡Gracias! – Geo

3
stuff_to_do = lambda do 
    # this happens in the thread 
end 

x = Thread.new(&stuff_to_do) 
+0

¿Cómo creo el hilo sin iniciarlo? – Geo

+0

¿Qué hace el ampersand? El código se rompe sin él, pero quiero entender la sintaxis. –

2

ignorar el example from Ruby-Doc 1.8.7, ya que contiene una condición de carrera. Ver Ruby 2 example, o algo como lo siguiente:

He probado esto en Ruby 2.0 y Ruby 1.8.7, y me encontré con que llamar #wakeup no era suficiente en 1.8.7' que tenía que llamar #run. El siguiente parece funcionar en ambos:

t = Thread.new { Thread.stop; puts "HELLO" } 
until t.stop?; end # ensure thread has actually stopped before we tell it to resume 
t.run 
+3

Esto tiene una condición de carrera. Si el t.run ocurre antes del Thread.stop, entonces el hilo nunca pasará eso. – ChrisPhoenix

+0

Chris tiene razón. De hecho, me encontré con esta condición. Actualicé la publicación con una espera ocupada para evitar la carrera. – Patrick

Cuestiones relacionadas