I recently got absorbed by threads in Perl. Why? Well, because I'm working on a product - iSMS - that I hope to be of use to some with some money to spend, otherwise it'll go OSS as is its predesessor. Anyway ... I want to use threads instead of the fork() or IO multiplexing via select().
So I set off reading about and experimenting with the new Perl threading implementation. A search on Google for some 'prior art' on Perl threads gave me the following site that compares threading in different languages.
I just compiled 5.6.1 with -Duse5005threads and checked the Thread implementation with the threads implementation in 5.8.0, sorta ...
The following 'apps' were used:
---------------- Thread
#!/opt/perl561t/bin/perl
use strict;
use Thread qw(cond_wait cond_signal);
my $count = 0;
my $data = 0;
my $produced = 0;
my $consumed = 0;
sub consumer {
my $n = shift;
while (1) {
lock($count);
cond_wait($count) while ($count == 0);
my $i = $data;
$count = 0;
$consumed++;
last if ($i == $n);
cond_signal($count);
}
}
sub producer {
my $n = shift;
for (my $i=1; $i<=$n; $i++) {
lock($count);
cond_wait($count) while ($count == 1);
$data = $i;
$count = 1;
$produced++;
cond_signal($count);
}
}
sub main {
my $n = ($ARGV[0] < 1) ? 1 : $ARGV[0];
my $p = Thread->new(\&producer, $n);
my $c = Thread->new(\&consumer, $n);
$p->join;
$c->join;
print "$produced $consumed\n";
}
main;
---------------- threads
#!/opt/perl58/bin/perl
use strict;
use threads;
use threads::shared;
my $count : shared = 0;
my $data : shared = 0;
my $produced :shared = 0;
my $consumed : shared = 0;
sub consumer {
my $n = shift;
while (1) {
lock($count);
cond_wait($count) while ($count == 0);
my $i = $data;
$count = 0;
$consumed++;
last if ($i == $n);
cond_signal($count);
}
}
sub producer {
my $n = shift;
for (my $i=1; $i<=$n; $i++) {
lock($count);
cond_wait($count) while ($count == 1);
$data = $i;
$count = 1;
$produced++;
cond_signal($count);
}
}
sub main {
my $n = ($ARGV[0] < 1) ? 1 : $ARGV[0];
my $p = threads->new(\&producer, $n);
my $c = threads->new(\&consumer, $n);
$p->join;
$c->join;
print "$produced $consumed\n";
}
main;
---------------------------------------
I got the following test-bench results and was a bit astonished
> time ./prodcon561.pl 100000
100000 100000
real 0m10.287s
user 0m5.360s
sys 0m4.930s
> time ./prodcon580.pl 100000
100000 100000
real 0m15.660s
user 0m11.780s
sys 0m3.880s
Subsequent runs give the same result ... ithreads are 50% slower than the 5005 threading model.
I've done a multithreading daemon in Perl 5.5(something) around 2000 to 2001 and found it rather stable enough for production capabilities ... although all advisory texts show me otherwise...
Anyway ... I guess this result has to do with the fact that ithreads don't share data by default. So an extra copy (clone) of variables can be the cause. Again ... speed has been traided for ease-of-use (and thread safety).
Hummm ... bad news ...
Anyway ... no hard feelings ... if I can get the expected performance ... no harm is done anyway.
For the curious - and now I assume other people are actually reading this weblog - I'm using threading in my *product* in the following way ...
First a boss/worker kind of thingy, in which incoming requests - handled by the boss - are passed to a worker which will handle the request. This way we get a better response time...
Secondly a thread is launched at application start that implements a HTTP daemon. This daemon is used for configuration of the application. This thread implements an embedded web server used for handling the configuration ...
Aha ... and as a last treat something I've been working on lately also - patterns in Perl. I was just skimming the new google news site for Perl news and found a rather intrigueing article a bout a guy who is trying to get his 'Patterns in Perl' book published ... It's a rather sad post, but the good thing is his work on patterns in perl. He deserves a publisher if you ask me ... even if it only was for hist effort (can't comment on the book quality though ... had no time to read it). The post can be found on:
http://www.advogato.org/article/579.html
We'll we are at it, you can also look at another PIP initiative: http://patternsinperl.com/
Regards,
Johan