Concurrency and AnyEvent::MPRPC
Marc Lehmann
schmorp at schmorp.de
Wed Sep 14 10:57:28 CEST 2011
On Tue, Sep 13, 2011 at 06:13:41PM +0200, Tobias Nissen <tn at movb.de> wrote:
> I'm using AnyEvent::MPRPC and I'd like for each remotely called method
> to be executed as a separate thread on the server (with a limitation
> on the number of concurrently running threads, of course). Now I spent
> much of the day reading about the different possible threading
> approaches, including Coro, but I think I'm more disoriented than
> before :-)
Coro is fine for concurrently running threads, but they will not use more
than one cpu, or otherwise run in parallel for any appreciable amount of
time.
If you mean threads in the sense of kernel threads running in parallel on
multiple cpus, then perl simply doesn't provide it (nor does any other
scripting language, for very complicted reasons). Nor are those threads
meant to scale well for multi core or multi cpu configurations.
As for forking, POSIX is quite unhelpful there, as forking in a perl that
uses pthreads (e.g. via ithreads, Coro on some platforms, or stuff like
IO::AIO) is not supported by POSIX anymore.
In practise, GNU/Linux does support fork in threaded programs, and most
bsds are on the road to allow that too, so using multiple forks is
certainly a viable approach in practise.
If you are not CPU bound, then Coro is also viable - except you have to
make sure never to block the whole process, which is easy once you learned
it, and possibly hard in the beginning.
Completely fine, and actually scalable are things like AnyEvent::MP, the
drawback there is the high setup cost, but the advantage is that it scales
well beyond a single host.
> Could you push me into the right direction? What would be relatively
> easy and straightforward to use and how would I integrate it?
I have no experience with Parallell::ForkManager, but if you fork often and
your program is large, then things tend to get slow. Also, if you use
soemthing that uses epoll (e.g. EV), then performance might be abysmal, as
epoll regulalry fails after forks.
If your forks are long-running, then you should start them as soon as
possible but after loading everything you need in those subprocesses,
to enhance sharing. Otherwise, if your process is big and you fork off
long-running processes, you might suffer from having a lot of cow-memory
being copied, taking alot of unused ram.
Comversely, having lots of short-lived forks is also not good for
performanc,e as fork is very far from being free.
So in short, things are complicated. Best is to not worry about
performance (you often don't need high performance, fast enough is fast
enough...) and go for the solution that gets your implementation done
fastest.
> I'd like to know if there are arguments against the way I'm doing it
> right now. Can you think of problems that might arise using AnyEvent
> with ForkManager like this?
Apart from likely very bad performance with EV+epoll (forcing select might
fix that), not really. You have to make sure to not initialise AnyEvent in
the parent if you want to use AnyEvent in the child, of course, or nt use
AnyEvent in the child when using it in the parent.
--
The choice of a Deliantra, the free code+content MORPG
-----==- _GNU_ http://www.deliantra.net
----==-- _ generation
---==---(_)__ __ ____ __ Marc Lehmann
--==---/ / _ \/ // /\ \/ / schmorp at schmorp.de
-=====/_/_//_/\_,_/ /_/\_\
More information about the anyevent
mailing list