2010-08-22 19 views
10

Si no, ¿cuál es el máximo sin dejar de ser eficiente?¿existe un límite en la cantidad de hilos que ruby ​​puede ejecutar a la vez?

Estoy creando 14 hilos, cada uno de los cuales abre una lista de URL (alrededor de 500) crea un nuevo hilo para cada uno, que luego lo descarga y lo agrega a un MySQL db. El tamaño del grupo de MySQL está establecido en 50.

Esta es una tarea de rake en RoR.

¿Funcionaría mejor usando Kernal#fork o algún otro método?

+3

¡puedes 'ruin' bastantes! ;) –

+0

arregló eso, gracias! no revisó el título: O – loosecannon

Respuesta

2

Bueno, dado que sus hilos van a estar enlazados, la buena noticia es que ambos hilos Ruby 1.8 y 1.9 funcionarán para esto. Ruby 1.8 usa "hilos de espacio de usuario", lo que significa que no se crean nuevos hilos de sistema operativo cuando se crean nuevos hilos en Ruby. Esto es malo para la multitarea de CPU, ya que solo un subproceso de Ruby se está ejecutando a la vez, pero es bueno para la multitarea de IO. Ruby 1.9 usa hilos reales, y será bueno para cualquiera.

La cantidad de hilos que puede crear realmente depende de su sistema. Por supuesto, existen límites prácticos, pero es probable que no quiera acercarse a ellos. En primer lugar, a menos que los servidores que está descargando sean muy lentos y su conexión sea muy rápida, solo unos pocos hilos saturarán su conexión a Internet. Además, si atrapa muchas páginas de un solo servidor, lanzar 500 solicitudes a la vez desde 500 hilos tampoco servirá de nada.

Comenzaría bastante pequeño: 10 o 20 hilos corriendo a la vez. Aumente o disminuya esto dependiendo de la carga del servidor, su ancho de banda, etc. También existe el problema de las conexiones concurrentes a la base de datos MySQL. Dependiendo de cómo estén configuradas sus tablas y de su tamaño, intentar insertar demasiados datos al mismo tiempo no va a funcionar muy bien.

+0

terminé abandonando el enhebrado y agregué un índice a la base de datos que hacía que buscar duplicados 1000 veces más rápido por lo que ya no necesitaba el aumento de velocidad, y como dijiste simplemente cargó mi conexión. ¡Gracias! – loosecannon

3

Con Ruby 1.8, está prácticamente limitado a la cantidad de memoria que tiene. Puedes crear decenas de miles de hilos por proceso. El intérprete de Ruby maneja la gestión de los hilos y solo se crean uno o dos hilos nativos. No es una verdadera multitarea cuando la CPU alterna entre subprocesos.

Ruby 1.9 usa subprocesos nativos. El límite parece ser lo que permite el SO. Solo para probar, puedo crear más de 2000 subprocesos en mi mac con Ruby 1.9 antes de que el SO no permita más.

Tenga en cuenta que tener miles de subprocesos para un proceso no es una buena idea. La programación del hilo se convierte en una carga mucho antes de eso.

+0

ok gracias! tal vez solo use esos primeros 14, y no todos los subhilos. Gracias! – loosecannon

+0

¿Quiere decir prácticamente ilimitado? (y sí, tener más hilos hace que su aplicación se ejecute ... más despacio ... en 1.8.6 debido a las referencias compartidas para el GC, aunque supongo que podría usar REE para evitar eso). – rogerdpack

+0

No, ciertamente no es ilimitado. Estoy seguro de que está de acuerdo en que está "limitado en la práctica" por la cantidad de memoria RAM disponible. – Alkaline

9
require 'open-uri' 
a = 'http://www.example.com ' * 30 
arr = a.split(' ') 

arr.each_slice(3) do |group| 
    group.map do |site| 
    Thread.new do 
     open(site) 
     p 'finished' 
    end 
    end.each(&:join) 
end 
+0

buen ejemplo. +1 de mi parte – Rubyrider

+0

Me gusta mucho poder crear subprocesos usando cada_slice. Nunca usé each_slice antes, así que esta es una solución muy esclarecedora –

Cuestiones relacionadas