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 (by sh4van3)

  • 0 Respuestas
  • 1451 Vistas

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

Conectado ANTRAX

  • *
  • Administrator
  • Mensajes: 5380
  • Actividad:
    75%
  • Reputación 31
  • ANTRAX
    • Ver Perfil
    • Underc0de
    • Email
  • Skype: underc0de.org
  • Twitter: @Underc0de
« en: Febrero 24, 2010, 04:18:19 pm »
HILOS

Ruby permite poder realizar varios procesos al mismo tiempo. Esto lo hace mediante los hilos. Los hilos son una manera r?pida 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 m?s ?til.

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. Ser? de 5 elementos y cada uno de ellos sera un hilo(Esto lo veremos a continuaci?n ;))
  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 explicar? esto m?s detenidamente).

Esto dar?a como resultado:
Citar
hola
esto
es
un
ejemplo

Esto lo podemos hacer por medio del "each". Por ejemplo, el code anterior con "each" ser?a as?:

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}
  12.  

Ahora vamos a pasar a hacer una aplicaci?n algo m?s compleja. Vamos a suponer un scanner de puertos que escanee de forma simult?nea 3 dominios en un puerto determinado. Ser?a as?:

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 dar? 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 m?todos 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 tendr?n 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, guard?ndolo mediante []= y llamandolo mediante []. Ve?moslo:

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}"
  12.  

Esto producir?a:
Citar
8, 0, 3, 7 2, 1, 6, 5, 4, 9, count = 10


Vamos a poner otro ejemplo para que lo comprend?is 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
  21.  

Esto dar?a 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 har?amos 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
  19.  
  20. hilo.each{|ele| ele.join; puts ele["www.code-makers.es"]}
  21.  

Esto nos dar?a 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.

Documentaci?n:

No tienes permisos para ver links. Registrate o Entra con tu cuenta
No tienes permisos para ver links. Registrate o Entra con tu cuenta
« Última modificación: Julio 31, 2014, 10:15:50 pm por Expermicid »


 

¿Te gustó el post? COMPARTILO!



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

Iniciado por ANTRAX

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

Iniciado por Alejandro9999

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

Iniciado por Alejandro9999

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

Iniciado por Alejandro9999

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

Iniciado por Alejandro9999

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