Threads in Perl, Erlang style

Adam Kennedy's recent post on threads in Padre reminded me to post about an experiment of mine. Last year I learned some Erlang. I really liked their model of multi-threading: many threads that share no data at all and communicate through message queues. A lot of other things where really annoying though, specially their crappy support for strings and lack of libraries in general. I kept thinking I want perl with these threads, so I started implementing it. And thus threads::lite was born.

The main difference between threads::lite and threads.pm is that t::l starts an entirely new interpreter instead of cloning the existing one. If you've loaded a lot of modules, that can be significantly quicker and leaner than cloning. As an optimization, it supports cloning itself right after module loading, so you can quickly start a large number of identical threads. Threads can be monitored, so that on thread death their send an exit code to their listeners.

Every thread has it's own message queue. Every thread can send messages to any thread whose thread-id it knows. Any kind of data that can be serialized using Storable can be send, including coderefs.

Receiving messages is done on basis of pattern matching (based on smart matching). This can range from a simple null-pattern (matches anything, so returns the front message on the queue) to complex tables of patterns.

I've started building some high level abstractions on top of it, most notably a implementation of a parallel map and grep. I'd like to do a map-reduce, but that's for a later stage.

This is very much an experimental module. I'm still not sure perl is really suitable for true erlang style threading: I suspect perl interpreters are to heavy to have a 100000 of them in one process, but it would be interesting to try…

9 Comments

Cool.

I've got nothing else to say right now, but I'm just commenting to let you know I've read your post with much interest. So you know you are not alone in a Perl desert... :)

So, like Coro / Coro::MP: channels, message passing, separate perl interpreters, except with ithreads?

Exactly how does the matching work? I took a look at the docs & source, but it wasn't clear to me (disclaimer: I have far too much blood in my caffeine stream at the moment, so this may not be a problem with the docs....)

This is really interesting -- just a couple months ago, I started thinking about the ease and power offered by software built on the message-passing model, and began working on my own design for a Perl 5 messaging layer. Since then, I've found that three or four other people are also diving into the space, everybody coming at it from a slightly different point of view.

I think this is pretty awesome all around, and it makes me want to work really fast, but I'm making myself actually write out a protocol spec and try to handle as many issues as I can on paper before I start coding, shooting for a balance between BDUF and making decisions on the fly.

Looks familiar:

Thread::Apartment

Tho it was based on regular Perl ithreads, it used msg passing. But relying on Thread::Queue and esp Storable turns out to be very expensive. Some related stuff:

DBIx::Threaded HTTP::Daemon::Threaded

fwiw, I tested using a regular new thread and starting a new interpreter...the performance benefit vs. starting a threadpool upfront in ithreads wasn't that great. The bigger issue is passing the msgs around wo/ having a major lock on the universe (which I was trying to solve w/ Thread::Sociable, until I tired of pushing a big rock up Perl's hill).

IMO, perl is not really ready or even feasible to be used for erlang style threadining. I believe it can be but it's far from ready. We tested this out a few times with my development team and had errors come up like clockwork with complex tables.

Bonnie Smith COO/Director FXP http://www.forexpulse.com

Leave a comment

About Leon Timmermans

user-pic