views:

599

answers:

7

Is it a bad idea to write multithreaded programs (specifically, TCP server daemons) in Perl?

+1  A: 

I don't know that I would say it's a bad idea, but I would say there are much better options when dealing with problem domains requiring multi-threading.

A better option in my opinion would be C/C++, but depending on your skill-set and you're experience with those languages, you may find it difficult/time consuming to write it. My advice would be to write it in Perl (I'm assuming that is your language of choice based on the question) and if it becomes a problem or you have performance issues then look into moving that code over to something like C/C++.

RC
Much better options..like ??
someguy
Such as? How do you know? (Not doubting your remark, just saying it could be more helpful.)
reinierpost
+5  A: 

It depends on the version of Perl you are using and the operating system you are on. See Bugs and Limitations in perldoc threads.

Sinan Ünür
i did check the forum..on threads for perl..lots of memory leak issues..so probably its a bad idea..
someguy
+3  A: 

Go ahead and write your server in Perl using ithreads. If it becomes a burden to duplicate the interpreter, your initial implementation serves as a prototype, and you will be able to translate your application logic easily into C, say. See perldoc perlthrtut.

Ewan Todd
So its better if i write my multi threaded server in C??:)
someguy
It's good to write your server correctly. That's easy enough to do in perl, even with a tricky items like a multithreaded server. If you perl implementation has enough performance for your app, then you are finished. Quickly.If you find you do need more performance, then you can use your perl implementation as a template when you move to a compiled implementation.Either way, I'd start with the scripted (perl) version.
Ewan Todd
+6  A: 

Perl is a great language for a server. If you come to any areas where interpreted code is bogging down the application, you can write extension code in C to handle it.

You might also look at non-blocking I/O to avoid the overhead of threads. IO::Lambda is a nice module for that, simplifying event-based programming to a few [anonymous] subroutines.

Jeff Ober
+1  A: 

Yes, it is a bad idea. Here is an article describing why it is so: Things you need to know before programming Perl ithreads

Here's just an excerpt from the aforementioned post:

Unlike most other threads implementations that exist in the world, including the older perl 5.005 threads implementation, variables are by default not shared between Perl ithreads. So what does that mean? It means that every time you start a thread all data structures are copied to the new thread. And when I say all, I mean all. This e.g. includes package stashes, global variables, lexicals in scope. Everything! An example:

use threads ();
my $foo;
threads->new( sub {print "thread: coderef = ".\$foo."\n"} )->join;
print "  main: coderef = ".\$foo."\n";

which prints this on my system:

thread: coderef = SCALAR(0x1eefb4)
  main: coderef = SCALAR(0x107c90)

But wait, you might say, shared variables may be a lot better. So why don't I make all variables shared in my application so I won't suffer from this. Well, that is wrong. Why? Because shared variables in fact aren't shared at all. Shared variables are in fact ordinary tied variables (with all the caveats and performance issues associated with tied variables) that have some "magic" applied to them. So, not only do shared variables take up the same amount of memory as "normal" variables, they take up extra memory because all of the tied magic associated with it. This also means that you cannot have shared variables with your own tie-magic associated with it (unless you want to use my Thread::Tie module).

roddik
This does sound like a horrible limitation. Might one get around it by using `Sys::Mmap` or some sort of `memcached` support (and storing most of one's active shared data therein)?
Jim Dennis
I guess there is some way to work around these, but it will probably take more time and bugs-fixing then writing the app in some other language with proper threading support
roddik
+4  A: 

I'd write such a thing in with POE, and then let POE::Wheel::Run fork off separate processes as needed.

daotoad
+2  A: 

Although, it's possible, I wouldn't do it. You can't do pre-spawning of threads, since you can't pass a new socket to existing threads.

Thread creation on a as needed basis can be very expensive, since all data structures are copied, for every new thread. With a simple program, that's okay, but if you loaded a a lot of stuff in memory first, it's prohibitive.

Because of this, I have used POE and AnyEvent, in separate project, when I needed a network server. They are not threaded, but at least you can handle multiple connection in a somewhat sane way. They work well on Windows and Linux, and both worked really well for my needs.

Mathieu Longtin