Event driven server that wastes CPU when threaded doesn't

Bryan Olson fakeaddress at nowhere.org
Thu Nov 2 05:52:33 EST 2006


Jean-Paul Calderone wrote:
> On Tue, 31 Oct 2006 07:33:59 GMT, Bryan Olson <fakeaddress at nowhere.org> 
> wrote:
>> Snor wrote:
>>> I'm attempting to create a lobby & game server for a multiplayer game,
>>> and have hit a problem early on with the server design. I am stuck
>>> between using a threaded server, and using an event driven server. I've
>>> been told time and time again that I should use an event driven server
>>> design (that is, use twisted).
>>
>> I didn't hear the specifics of how you got that advice, so I
>> can't comment specifically. I will say that I've have heard a
>> lot of advice against threads that struck me as simply naive.
> 
> Much of it is quite well informed.

Could be; I didn't see it all. A lot was naive; I'd even say that
the majority was naive. The most sophisticated software -- DBMS's,
modern operating systems, avionics -- deals with multiple lines of
control. I'm not saying that playing at that level is easy. The
difficult problems are fundamental, and single-tasking merely takes
away important capabilities.


>>> There is a lot of interaction between the clients and they would often
>>> need to write to the same list of values, which of course becomes a
>>> problem with a threaded server - so event driven solves that problem,
>>> and I assumed it would solve all my problems. [...]
>>
>> The purely event-driven style solves some problems, but creates
>> others. You're forced to structure your code around the blocking
>> behavior, and that's not the structure anyone would choose for
>> clarity or maintainability.
> 
> This is not the case. 

What I claimed is the case is the case.

> However, much event-driven code is written
> this way anyway, intentionally, for clarity. If you _want_ opaque
> code, or for some reason think it is not opaque to write code in this
> manner, then there you can use a library which supports this.

Read the greats on the subject: modules should exhibit loose coupling
and tight cohesion. But the purely event-driven style imposes a rule
that must trump the principles of elegant design: no procedure, no
method, may include and encapsulate an operation that might block.
That's not for clarity; it's a limitation; it's broken.

>> Suppose we're enhancing an event-driven system, and decide to
>> relocate some datum from a variable to the database. Suppose in
>> one or more places, accessing the data happens in a call chain
>> several function down from the event loop. We can't just change
>> the function that accesses the data because a synchronous
>> database call could block and stop event processing. Every
>> interface on the call chain is broken.
> 
> As it must be, because you have changed the atomicity of an
> operation.

That's just naive. A thread switch and a return to the event
loop both have the chance to break atomicity, as do other
things.

> Transparently propagating this up a call stack leads to bugs which are
> similar to those found in a system based on pre-emptive multithreading.

Yet "system based on pre-emptive multithreading" are taking over.
Might as well get with the modern world. The competitive operating
systems are multi-threaded and multi-core hardware is now at the
local Best-Buy.

I'm not saying threads are trivial to master. I did not start out
at an advocate for programming with multiple threads and/or
processes. But I think the race is over, and even those that think
it's still on should be able to see that multiple lines of control
are both in lead and moving faster.


>> [...]
>>> I will want the server to support as many users as is possible on any
>>> given machine - and so wasted CPU cycles is something I am trying to
>>> avoid.
>>
>> Python is a great scripting language, but squeezing out machine
>> performance is not where scripting languages shine. That said, you
>> might start in Python, to see if your system is successful and the
>> performance of your server really is a limiting factor.
>>
>>
>>> Is the only solution to use a threaded server to let my clients make
>>> their requests and receive a response in the fastest possible time?
>>
>> Maybe. Probably not. It's all good -- multi-threading is your friend.
> 
> Multithreading is _someone's_ friend.  Probably not the OP's, whose
> original post made it sound very strongly like he just needed network
> concurrency, which is a perfectly fine use-case for event-driven style
> rather than pre-emptive threading.

I suggested he might start in Python (which has a global interpreter
lock) to see if his system gets the traction it needs.
But obviously no one is going to build a /World of Warcraft/ without
learning to deal with multiple simultaneous lines of execution.

It's all good. Multi-threading can be your friend too.


-- 
--Bryan




More information about the Python-list mailing list