tags:

views:

724

answers:

3

In python we can use multiprocessing modules. If there is a similar library in Perl and Ruby, would you teach it? I would appreciate it if you can include a brief sample.

+10  A: 

Ruby:

Perl:

Also, Perl's threads are native operating system threads, so you can just use those to take advantage of multiple cores.

musicfreak
Sadly, Python is also a victim of the GIL.
TM
JRuby does threads just fine. I'm sure that IronRuby does threads just fine. And when ruby gets a better native VM, they'll be able to do threads just fine.
sal
I don't think Ruby will ever support native OS-level threads. Matz said he's looking at parallel processing via some kind of "mini processes" a la Erlang.
musicfreak
@TM: Yeah, but Python 2.6 has the multiprocessing library which, while not as efficient as threads, does allow concurrent processing.
musicfreak
+8  A: 

With Perl, you have options. One option is to use processes as below. I need to look up how to write the analogous program using threads but http://perldoc.perl.org/perlthrtut.html should give you an idea.

#!/usr/bin/perl

use strict;
use warnings;

use Parallel::ForkManager;

my @data = (0 .. 19);

my $pm = Parallel::ForkManager->new(4);

for my $n ( @data ) {
    my $pid = $pm->start and next;
    warn sprintf "%d^3 = %d\n", $n, slow_cube($n);
    $pm->finish;
}

sub slow_cube {
    my ($n) = @_;

    sleep 1;
    return $n * $n * $n;
}

__END__

The following version using threads does not use a limit on the number of threads created (because I do not know how):

#!/usr/bin/perl

use strict;
use warnings;

use threads;

my @data = (0 .. 19);
my @threads = map { 
    threads->new( {context => 'list' }, \&slow_cube, $_ )
} @data;

for my $thr ( @threads ) {
    my ( $n, $ncubed ) = $thr->join;
    print "$n^3 = $ncubed\n";
}

sub slow_cube {
    my ($n) = @_;

    sleep 1;
    return $n, $n * $n * $n;
}

__END__

Interestingly:

TimeThis :  Command Line :  t.pl
TimeThis :  Elapsed Time :  00:00:01.281
Sinan Ünür
Perl's threads are expensive, both in startup time and in memory. They are best used on an ongoing basis, not once-off as above - but for that, separate processes are often going to be better. Perl 6 syntax offers a lot of areas for multiprocessing to be used naturally...someday.
ysth
Another option is to use forks (http://search.cpan.org/~rybskej/forks-0.33/lib/forks.pm) to emulate threads via IPC which is actually pretty fast on POSIX systems.
jiggy
+2  A: 

Check out Coro which provide coroutines to Perl.

Here is an excerpt from the authors docs....

This module collection manages continuations in general, most often in the form of cooperative threads (also called coros, or simply "coro" in the documentation). They are similar to kernel threads but don't (in general) run in parallel at the same time even on SMP machines. The specific flavor of thread offered by this module also guarantees you that it will not switch between threads unless necessary, at easily-identified points in your program, so locking and parallel access are rarely an issue, making thread programming much safer and easier than using other thread models.

Unlike the so-called "Perl threads" (which are not actually real threads but only the windows process emulation ported to unix, and as such act as processes), Coro provides a full shared address space, which makes communication between threads very easy. And Coro's threads are fast, too: disabling the Windows process emulation code in your perl and using Coro can easily result in a two to four times speed increase for your programs. A parallel matrix multiplication benchmark runs over 300 times faster on a single core than perl's pseudo-threads on a quad core using all four cores.


For something similar to above in Ruby then have a look at Fiber which comes with Ruby 1.9.

Here are two interesting articles on using Fiber:

There is also a Fiber for Perl using Coro. Here are some articles about Fiber for Perl (in Japanese):

/I3az/

draegtun