2012-04-02 7 views
29

Si desea aprender cómo usar hilos de intérprete Perl, hay buena documentación en perlthrtut (threads tutorial) y the threads pragma manpage. Definitivamente es lo suficientemente bueno para escribir algunos scripts simples.¿Casos de uso para ithreads (hilos de intérprete) en Perl y razones para usarlos o no?

Sin embargo, he encontrado poca orientación en la web en qué y lo utilizar con sensatez hilos intérprete de Perl para. De hecho, no se habla mucho de ellos, y si la gente habla de ellos, con frecuencia es para desalentar a las personas a usarlos.

Estos hilos, disponible cuando perl -V:useithreads es useithreads='define'; y desatada por use threads, también son llamados iThreads, y tal vez más apropiadamente de modo ya que son muy diferentes de hilos como los ofrecidos por los sistemas operativos Linux o Windows o la máquina virtual de Java en que no se comparte nada por defecto y en su lugar se copian muchos datos, no solo la pila de subprocesos, lo que aumenta significativamente el tamaño del proceso. (Para ver el efecto, cargar algunos módulos en un script de prueba, a continuación, crear hilos en un bucle de una pausa de pulsaciones de tecla cada vez, y ver aumento de memoria en el administrador de tareas o top.)

[...] cada vez que inicia un hilo, todas las estructuras de datos se copian en el nuevo hilo. Y cuando digo todo, quiero decir todo. Esto p. incluye paquetes stashes, variables globales, léxicos en el alcance. ¡Todo!

- Things you need to know before programming Perl ithreads (Perlmonks 2003)

Al investigar el tema de iThreads Perl, verá la gente que desalentar el uso de ellos ("extremely bad idea", "fundamentally flawed", o "never use ithreads for anything").

The Perl thread tutorial highlights that "Perl Threads Are Different", pero no se molesta en explicar cómo son diferentes y qué significa eso para el usuario.

Una explicación útil pero muy breve de lo que realmente son los hilos es from the Coro manpage under the heading WINDOWS PROCESS EMULATION. El autor de ese módulo (Coro - los únicos hilos reales en perl) también desalienta el uso de hilos de intérprete Perl.

En algún lugar he leído que la compilación de Perl con subprocesos habilitados dará como resultado un intérprete significativamente más lento.

Hay una página de Perlmonks de 2003 (Things you need to know before programming Perl ithreads), en la que el autor pregunta: "Ahora se puede preguntar por qué Perl ithreads no usó fork()? ¿No habría tenido mucho más sentido?" Esto parece haber sido escrito por el autor del pragma forks. No estoy seguro de que la información que figura en esa página aún sea cierta en 2012 para los Perls más nuevos.

Aquí hay algunas pautas para el uso de hilos en Perl he destilados de mis lecturas (tal vez erróneamente): por lo

Hasta ahora mi investigación. Ahora, gracias por más luz que puede arrojar sobre este tema de hilos en Perl. ¿Cuáles son algunos casos de uso sensato para ithreads en Perl? ¿Cuál es la razón para usar o no usarlos?

Respuesta

21

La respuesta corta es que son bastante pesados ​​(no se pueden lanzar 100+ de ellos a bajo precio), y exhiben comportamientos inesperados (algo mitigados por los recientes módulos de CPAN).

Usted puede utilizar con seguridad iThreads Perl tratándolos como actores independientes.

  1. Crear un hilo :: Queue :: Any for "work".
  2. Ejecutar múltiples ithreads y colas de "resultado" pasándolas ("trabajo" + propio "resultado") Colas por cierre.
  3. Cargue (requiera) todo el código restante que su aplicación requiera (¡no antes de los hilos!)
  4. Agregue trabajo para los hilos en la cola según sea necesario.

En iThreads "trabajador":

  1. Llevar en cualquier código común (para cualquier tipo de trabajo)
  2. bloqueo-dequeue una pieza de trabajo de la cola
  3. demanda-cargar cualquier otras dependencias requeridas para este trabajo.
  4. Haga el trabajo.
  5. Pase el resultado de vuelta al hilo principal a través de la cola "resultado".
  6. Volver a 2.

Si algunos hilos "trabajadores" empiezan a ser un poco carnosos, y hay que limitar "trabajador" hilos a algún número a continuación, poner en marcha otros nuevos en su lugar, a continuación, crear un " iniciador "hilo primero, cuyo trabajo es iniciar subprocesos" trabajador "y conectarlos al hilo principal.

¿Cuáles son los principales problemas con Perl ithreads?

Son un poco incómodos con los datos "compartidos", ya que es necesario compartir explícitamente (no es un gran problema).

usted necesita mirar hacia fuera para el comportamiento de los objetos con destruir métodos, ya que ir fuera de campo en un poco de hilo

El grande (si todavía están obligados en otro!): Datos/variables que no se comparten explícitamente son CLONED en nuevos hilos. Este es un golpe de rendimiento y probablemente no sea lo que pretendías. La solución alternativa es lanzar ithreads desde una condición bastante "prístina" (no muchos módulos cargados).

IIRC, hay módulos en el espacio de nombres Threads :: que ayudan a hacer que las dependencias sean explícitas y/o limpiar los datos clonados para nuevos subprocesos.

Además, IIRC, hay un modelo ligeramente diferente que usa hilos ith llamados hilos "Apartamento", implementado por Thread :: Appartment que tiene un patrón de uso diferente y otro conjunto de concesiones.

El resultado:

No los use a menos que sepa lo que está haciendo :-)

Tenedor puede ser más eficientes en Unix, pero la historia IPC es mucho más simple para ithreads. (Esto puede haber sido mitigado por los módulos de CPAN desde la última vez que miré :-)

Son aún mejor que los hilos de Python.

Es posible que, un día, ser algo mucho mejor en Perl 6.

+0

Gracias! Esta es la instrucción de uso más detallada para los hilos de Perl que he visto hasta la fecha. - En mi pregunta, indiqué que el * cómo * de usar ithreads está cubierto, mientras que el * por qué * y * qué para * están ausentes. Pensando más en esto, el * cómo *, el * por qué * y el * qué para * están estrechamente relacionados, y en realidad el * cómo * no ha sido lo suficientemente preciso (para los usuarios comunes de Perl como yo) para responder el * por qué * y para qué*. - Esta respuesta es un paso adelante. Gracias de nuevo. – Lumi

+0

"Todavía son mejores que los hilos de Python". - ¿Puede explicar esto? Por favor, es muy interesante – nordicdyno

+3

Principalmente se trata de Python GIL en la mayoría de las implementaciones (predominantemente cpython pero otras en menor extensión). Básicamente, significa que los subprocesos del sistema operativo en Python no pueden ejecutar el trabajo de la CPU al mismo tiempo, lo que los anula por completo. Puede usarlos (subprocesos de Python) para hacer que la E/S sea un poco más simultánea, pero es más fácil usar API orientadas a eventos para hacer eso. –

8

he utilizado "hilos" de Perl en varias ocasiones. Son más útiles para iniciar un proceso y continuar con otra cosa. No tengo mucha experiencia en la teoría de cómo funcionan bajo el capó, pero sí tengo mucha experiencia de codificación práctica con ellos.

Por ejemplo, tengo un hilo de servidor que escucha las conexiones de red entrantes y escupe una respuesta de estado cuando alguien lo solicita. Creo ese hilo, luego sigo y creo otro hilo que monitorea el sistema, verifica cinco elementos, duerme unos segundos y vuelve a hacer bucles. Puede tomar de 3 a 4 segundos recopilar los datos del monitor, luego se inserta en una variable compartida, y el hilo del servidor puede leer eso cuando sea necesario e inmediatamente devolver el último resultado conocido a quien lo solicite. El subproceso del monitor, cuando detecta que un elemento está en mal estado, inicia una cadena separada para reparar ese elemento. Luego se mueve, verifica los otros elementos mientras se repara el defectuoso y lanza otros hilos para otros artículos defectuosos o se une a los hilos de reparación terminados. El programa principal está bucleando cada pocos segundos, asegurándose de que el monitor y los hilos del servidor no se puedan unir/seguir funcionando. Todo esto podría escribirse como un conjunto de programas separados que utilizan alguna otra forma de IPC, pero los hilos de perl lo hacen simple.

Otro lugar donde los he usado está en un generador fractal. Me gustaría dividir partes de la imagen usando algún algoritmo y luego lanzar tantos hilos como CPU tenga para hacer el trabajo. Cada uno de ellos incluía sus resultados en un solo objeto GD, lo que no causaba problemas porque cada uno de ellos trabajaba en diferentes partes de la matriz, y luego, cuando terminaba, escribía la imagen GD. Fue mi introducción al uso de subprocesos perl, y fue una buena introducción, pero luego lo reescribí en C y fue dos órdenes de magnitud más rápido :-). Luego volví a escribir mi versión de Perl para utilizar Inline :: C, y fue solo un 20% más lenta que la versión C pura. Aún así, en la mayoría de los casos en los que desearía utilizar subprocesos debido a que consume mucha CPU, probablemente quiera simplemente elegir otro idioma.

Según lo mencionado por otros, el tenedor y los hilos realmente se superponen para muchos propósitos. Sin embargo, Coro no permite el uso de varias CPU o el procesamiento en paralelo, como tenedor e hilo, solo verá su proceso usando 100%. Estoy simplificando demasiado esto, pero creo que la forma más fácil de describir a Coro es que es un programador para sus subrutinas. Si tiene una subrutina que bloquea, puede saltar a otra y hacer otra cosa mientras espera, por ejemplo, si tiene una aplicación que calcula los resultados y los escribe en un archivo. Un bloque puede calcular resultados e insertarlos en un canal. Cuando se queda sin trabajo, otro bloque comienza a escribirlos en el disco. Mientras ese bloque está esperando en el disco, el otro bloque puede comenzar a calcular los resultados nuevamente si obtiene más trabajo. Es cierto que no he hecho mucho con Coro; suena como una buena forma de acelerar algunas cosas, pero estoy un poco desconcertado por no poder hacer dos cosas a la vez.

Mi preferencia personal, si quiero hacer multiprocesamiento, es usar tenedor si estoy haciendo muchas cosas pequeñas o cortas, hilos para un puñado de cosas grandes o de larga vida.

Cuestiones relacionadas