comment
IRC Chat
play_arrow
Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

Hilos en Ruby

  • 0 Respuestas
  • 4566 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Dharok

  • *
  • Underc0der
  • Mensajes: 111
  • Actividad:
    0%
  • Reputación 0
  • Siempre atento! Aun vivo.
    • Ver Perfil
    • Email
« en: Febrero 23, 2010, 11:19:55 pm »
HILOS

Ruby permite poder realizar varios procesos al mismo tiempo. Esto lo hace mediante los hilos. Los hilos son una manera rapida y eficiente para aumentar el paralelismo en nuestros programas. Vamos pues a crear hilos en Ruby. Comenzar? con un sencillo ejemplo y luego pasar? a uno mas util.

CREAR HILOS:

Los hilos se crean con la llamada a Thread.new:

Código: Ruby
  1. array=['hola', 'esto', 'es', 'un', 'ejemplo'] # Creamos un array de 5 elementos.
  2.  
  3. hilo=Array.new # Creamos un array para los hilos. Seria de 5 elementos y cada uno de ellos sera un hilo(Esto lo veremos a continuacion ;))
  4.  
  5.  
  6. for element in array #creamos un bloque
  7.    hilo<<Thread.new(element){|x| # Creamos un hilo para cada elemento y lo introducimos en el array hilo.
  8.    puts x # Hacemos que imprima por pantalla x
  9.    }
  10. end
  11.  
  12. hilo.each{|z| z.join} # Con este ultimo comando, nos aseguramos de que los hilos no mueran antes de que finalize el programa principal (luego se explicara esto mas detenidamente).

Esto dara como resultado:
Citar
hola
esto
es
un
ejemplo
Esto lo podemos hacer por medio del "each". Por ejemplo, el code anterior con "each" seria asi:
Código: Ruby
  1. array=['hola', 'esto', 'es', 'un', 'ejemplo']
  2.  
  3. hilo= Array.new
  4.  
  5. array.each{|element|
  6.    hilo<<Thread.new(element){|x|
  7.    puts x
  8.    }
  9. }
  10.  
  11. hilo.each{|ele| ele.join}
Ahora vamos a pasar a hacer una aplicaci?n algo m?s compleja. Vamos a suponer un scanner de puertos que escanee de forma simultanea 3 dominios en un puerto determinado. Seria asi:
Código: Ruby
  1. require 'socket'
  2.  
  3. paginas=['www.code-makers.es', 'www.google.com', 'www.youtube.com'] #Creamos el array con las 3 p?ginas.
  4.  
  5. hilo=Array.new
  6.  
  7. for pag in paginas
  8.    hilo<<Thread.new(pag){|x|
  9.    begin
  10.    TCPSocket.new(x, 21)
  11.    rescue
  12.    puts "21 cerrado en #{x}"
  13.    else
  14.    puts "21 abierto en #{x}"
  15.    end
  16.    sleep 1 #Damos un peque?o espacio de tiempo para que se termine el proceso.
  17.    begin
  18.    TCPSocket.new(x, 80)
  19.    rescue
  20.    puts "80 cerrado en #{x}"
  21.    else
  22.    puts "80 abierto en #{x}"
  23.    end
  24.    sleep 1
  25.    begin
  26.    TCPSocket.new(x, 81)
  27.    rescue
  28.    puts "81 cerrado en #{x}"
  29.    else
  30.    puts "81 abierto en #{x}"
  31.    end
  32.    }
  33. end
  34.  
  35. hilo.each{|ele| ele.join}
Esto dara como resultado:
Citar
21 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.
21 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.
21 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.
80 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.
80 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.
80 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.
81 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.
81 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.
81 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta abierto.

MANIPULAR HILOS:

Existen diversos metodos de la clase Thread que sirven para controlar los hilos:
Código: Ruby
  1. Thread.current # Nos devuelve el hilo que esta siendo ejecutado "<Thread:0x401bdf4c run>"
  2. Thread.list # Nos devuelve un array con los objetos para cada hilo diciendonos si estan corriendo o parados.
  3.    #<Thread:0x401b3e84 sleep>
  4.    #<Thread:0x401b3f38 run>
  5.    #<Thread:0x401b3fb0 sleep>
  6.    #<Thread:0x401bdf4c run>
  7. hilo.status # Nos devuelve el estatus del hilo. "run", "sleep", "aborting"
  8. Thread.kill(hilo) # Acaba con el proceso.
  9. Thread.start{|x| bloque} # Igual que Thread.new.
  10. Thread.stop # Deja durmiendo al hilo pero no lo mata.
  11. hilo.join # Cuando un programa en Ruby termina, los hilos en ejecuci?n se matan independientemente de su estado.
  12. #Con join lo que hacemos es esperar a que termine el hilo antes de matarlos. Digamos que con join te aseguras de que se realicen todos los procesos.
VARIABLES:

En los hilos, las variables locales al hilo, son solo accesibles en el propio hilo, ya que no se comparten fuera del mismo. Es decir, las variables que se establecen en el propio hilo no tendran validez fuera. Si queremos utilizar variables del hilo fuera del mismo, es decir, si queremos que estas variables tengan validez fuera del hilo, tenemos que tratar el objeto del hilo como si fuera un hash, guardandolo mediante []= y llamandolo mediante []. Veamoslo:
Código: Ruby
  1. count = 0
  2. arr = []
  3. 10.times do |i|
  4.   arr[i] = Thread.new {
  5.     sleep(rand(0)/10.0)
  6.     Thread.current["mycount"] = count # Asignamos la variable count a la llave del hash "mycount", que se guarda en hilo.
  7.     count += 1
  8.   }
  9. end
  10. arr.each {|t| t.join; print t["mycount"], ", " }
  11. puts "count = #{count}"
Esto producira:
Citar
8, 0, 3, 7 2, 1, 6, 5, 4, 9, count = 10


Vamos a poner otro ejemplo para que lo comprendeis mejor. Supongamos que tenemos un scanner de puertos y queremos imprimir la variable <a> fuera del hilo:
Código: Ruby
  1. require 'socket'
  2.  
  3. paginas=['www.code-makers.es', 'www.google.com', 'www.youtube.com'] #Creamos el array con las 3 p?ginas.
  4.  
  5. hilo=Array.new
  6.  
  7. for pag in paginas
  8.    hilo<<Thread.new(pag){|x|
  9.    begin
  10.    TCPSocket.new(x, 80)
  11.    rescue
  12.    a= "80 cerrado en #{x}"
  13.    else
  14.    a= "80 abierto en #{x}"
  15.    end
  16.    }
  17. end
  18.  
  19. hilo.each{|ele| ele.join}
  20. puts a
Esto daria como resultado un mensaje de error advirtiendonos de que la variable <a> no ha sido definida:
Citar
hilos.rb:20: undefined local variable or method `a' for main:Object (NameError)
Para solventar este problema hariamos lo siguiente:
Código: Ruby
  1. require 'socket'
  2.  
  3. paginas=['www.code-makers.es', 'www.google.com', 'www.youtube.com'] #Creamos el array con las 3 p?ginas.
  4.  
  5. hilo=Array.new
  6.  
  7. for pag in paginas
  8.    hilo<<Thread.new(pag){|x|
  9.    begin
  10.    TCPSocket.new(x, 80)
  11.    rescue
  12.    a= "80 cerrado en #{x}"
  13.    else
  14.    a= "80 abierto en #{x}"
  15.    end
  16.    Thread.current["#{x}"]=a # Asignamos la variable <a> a la llave del hash x (que ser? la p?gina web que se est? escaneando en ese momento), y la guardamos en hilo.
  17.    }
  18. end

Esto nos daria un resultado positivo:
Citar
80 abierto en No tienes permisos para ver links. Registrate o Entra con tu cuenta

Creo que con estos dos ejemplos han quedado claras las variables.
Documentacion

Documentacion oficial.(No tienes permisos para ver links. Registrate o Entra con tu cuenta)
Mis documentacion.(No tienes permisos para ver links. Registrate o Entra con tu cuenta)
AUTOR: sh4van3
« Última modificación: Julio 31, 2014, 09:43:58 pm por Expermicid »
No tienes permisos para ver links. Registrate o Entra con tu cuenta

 

¿Te gustó el post? COMPARTILO!



[Ruby] Traductor de Decimal a Ascii / Ascii a Decimal

Iniciado por ANTRAX

Respuestas: 0
Vistas: 1511
Último mensaje Febrero 24, 2010, 04:16:38 pm
por ANTRAX
Lenguaje Ruby, aprendiendo poco a poco.

Iniciado por Alejandro_99

Respuestas: 2
Vistas: 1525
Último mensaje Agosto 15, 2013, 02:58:39 pm
por Alejandro_99
Crafting rails 4 applications (Manual de Ruby on Rails 4)

Iniciado por Alejandro_99

Respuestas: 0
Vistas: 949
Último mensaje Marzo 01, 2014, 05:34:50 pm
por Alejandro_99
Desarrollo de aplicaciones Perl, PHP, Python y "Ruby on Rails"

Iniciado por Alejandro_99

Respuestas: 0
Vistas: 1193
Último mensaje Junio 13, 2014, 03:27:08 pm
por Alejandro_99
Como Instalar RubyMine y Crear un proyecto vacio para Ruby y Rails

Iniciado por Alejandro_99

Respuestas: 0
Vistas: 1710
Último mensaje Julio 07, 2013, 10:51:08 pm
por Alejandro_99