2009-09-26 13 views

Respuesta

7

Las versiones más recientes de Perl tienen soporte para enhebrar. Ejecute perl -V:usethreads para ver si está disponible en su sistema.

$ perl -V:usethreads 
usethreads='define' 

perldoc threads da una buena introducción al uso de ellos.

+2

Nunca use ithreads para nada. – jrockway

+0

Enlace no está funcionando –

7

Si el rendimiento no es un gran problema, entonces fork ing procesos múltiples es probable que haya mucho más fácil que tratar con hilos. Con frecuencia uso Parallel::ForkManager, que es muy simple, pero muy bueno en lo que hace.

5

Parece que no necesita un multihilo preemptivo; en ese caso, mire el modelo cooperativo POE. Como su código solo cederá a otros hilos cuando lo decida, y solo tendrá un hilo ejecutándose a la vez, el desarrollo y la depuración serán mucho más fáciles.

+3

A tener en cuenta es que, si bien POE no admite implícitamente multihilo o multiprocesamiento, 'POE :: Wheel :: Run' le permite ejecutar una pieza de código en un proceso en forma de horquilla, la traducción de su estado de E/S y la salida en eventos POE. A veces es una cosa muy útil para envolver el código de bloqueo. – hobbs

+0

En segundo lugar que _ – xxxxxxx

2

Coro es un módulo agradable para la multitarea cooperativa.

99% de las veces, esto es lo que necesita si quiere hilos en Perl.

Si desea hilos para acelerar su código cuando varios núcleos están disponibles, que van por el camino equivocado. Perl es 50 veces más lento que otros idiomas. Reescribir su código para que se ejecute en dos CPU significa que ahora solo funciona 25 veces más lento que otros lenguajes ... en una CPU. Es mejor gastar el esfuerzo trasladando las partes lentas a un idioma diferente.

Pero si lo que no quiere IO para bloquear otros "hilos", a continuación, Coro es exactamente lo que quiere.

+1

También hay una velocidad de desarrollo. –

+0

Estoy cansado de este argumento :) Hay muchas cosas que puedo hackear juntas tan rápido en Haskell como en Perl, y Haskell funciona mucho más rápido que Perl. – jrockway

+0

Estoy de acuerdo con partes de esto, pero afirmar que Perl es 50 veces más lento que otros idiomas es una exageración que solo se aplica a ciertas operaciones. Como saben, las expresiones regulares e IO de Perl están a la par de los mejores lenguajes compilados. Si un programador puede identificar cuellos de botella y tiene el tiempo del desarrollador, puede valer la pena escribir algún código en una DSL usando Inline :: C. Si tienen que volver a escribir la mayoría de su código en la DSL para obtener una buena aceleración en el rendimiento, entonces podría tener sentido soltar Perl por completo. –

9

Hay muchas razones por las que es posible que no desee multiprocesar. Sin embargo, si desea realizar subprocesos múltiples, el siguiente código podría servir como un ejemplo útil. Crea una cantidad de trabajos, los pone en una cola segura para subprocesos y luego inicia algunos subprocesos que extraen trabajos de la cola y los completan. Cada hilo sigue tirando trabajos de la cola en un bucle hasta que no ve más trabajos. El programa espera a que termine todo el hilo y luego imprime el tiempo total que pasó trabajando en los trabajos.

#!/usr/bin/perl 

use threads; 
use Thread::Queue; 
use Modern::Perl; 

my $queue= Thread::Queue->new; 
my $thread_count= 4; 
my $job_count= 10; 
my $start_time= time; 
my $max_job_time= 10; 

# Come up with some jobs and put them in a thread-safe queue. Each job 
# is a string with an id and a number of seconds to sleep. Jobs consist 
# of sleeping for the specified number of seconds. 
my @jobs= map {"$_," . (int(rand $max_job_time) + 1)} (1 .. $job_count); 
$queue->enqueue(@jobs); 

# List the jobs 
say "Jobs IDs: ", join(", ", map {(split /,/, $_)[0]} @jobs); 

# Start the threads 
my @threads= map {threads->create(sub {function($_)})} (1 .. $thread_count); 

# Wait for all the threads to complete their work 
$_->join for (@threads); 

# We're all done 
say "All done! Total time: ", time - $start_time; 

# Here's what each thread does. Each thread starts, then fetches jobs 
# from the job queue until there are no more jobs in the queue. Then, 
# the thread exists. 
sub function { 
    my $thread_id= shift; 
    my ($job, $job_id, $seconds); 
    while($job= $queue->dequeue_nb) { 
    ($job_id, $seconds)= split /,/, $job; 
    say "Thread $thread_id starting on job $job_id ", 
     "(job will take $seconds seconds)."; 
    sleep $seconds; 
    say "Thread $thread_id done with job $job_id."; 
    } 
    say "No more jobs for thread $thread_id; thread exiting."; 
} 
Cuestiones relacionadas