haskell httpd

Paul Graunke ptg at ccs.neu.edu
Thu Nov 6 08:38:10 EST 2003


On Wednesday, November 5, 2003, at 08:46 PM, ajb at spamcop.net wrote:

> G'day all.
>
> Quoting Peter Simons <simons at cryp.to>:
>
>> At least in my experience, multiplexing servers _are_
>> significantly faster than those relying on the OS (or
>> whatever library) to do the scheduling. They also tend to be
>> much more efficient in terms of memory consumption, thus
>> allowing for more simultaneous connections than a fork()ing
>> or pthread_xxx()ing server would. (Not a big surprise, if
>> you think about it.)

Right, cooperative multitasking is faster than preemptive multitasking.

>
> In my experience, it depends highly on the application.  I currently
> hack database servers for a living.  These have properties which are
> almost ideal for multithreading.  Requests tend to require a lot of
> work to satisfy, different requests often don't need the same resources
> (so the server isn't effectively sequential), many operations are I/O
> bound and so on.  Being able to exploit SMP concurrency and being able
> to get useful work done during iowait result in a net win.

Right, the more CPUs the merrier (for parallelizable tasks).
One technique is to have several OS threads to make use of CPUs and
do your own scheduling inside that.
>
> Yes, you can use asynchronous I/O, but I usually find this harder to
> understand than the equivalent multithreaded code.  select() and poll()
> may help, but they are hard to use in conjunction with other kinds of
> events which don't map to file descriptors, such as SysV semaphores,
> Unix signals, condition variables, GUI events etc.

Most event/select/poll implementations built in C by systems guys look
really messy.  Writing a single threaded program and then slapping a
forkIO around the code for a connection is convenient.  If all the IO
is monadic anyway, you might as well use a different monad instead.
Then IO can capture the continuation, store it in a run queue, and
yield to another coroutine.  (I think of cooperative threads as
coroutines + scheduling.)  All the do-it-yourself threading code is
in one place, leaving the structure of the rest of the code (fairly)
unmolested.
>
>> Aside from that, it appears to be impossible to combine
>> poll()-scheduled Haskell code with the "traditionally"
>> scheduled Haskell code in the same program -- unless you
>> count busy polling as a viable solution.

You do have the problem that any remaining blocking IO blocks
the whole bundle of cooperative threads.  I think the Portable
Common Runtime hands off blocking operations to a pool of preemptive
system threads to avoid this problem.
>
> I don't.  I don't count cycles as a rule (unless it really, REALLY
> matters, which it does on rare occasions), but burning as many as you
> can while doing precisely nothing is just plain wrong.
>
> There's a lot to be said for Win32's unified model of events.  Or it
> would if WaitForMultipleObjects() wasn't limited to an insanely small
> number of objects.  What I think I want is QNX-like pulses.  In the
> Haskell world, we come pretty close with channels and ports.  If there
> was a way to deliver system events via a Channel-like structure without
> busy polling, that would be really nice.
>
> Cheers,
> Andrew Bromage

Is there a problem with having a system thread do the IO based on
pulling events from a channel and pushing the results back to a
channel?  You can push the result channel/mvar through the request 
channel
along with the request.  This is the Erlang style, no?

Regards,

Paul



More information about the Haskell mailing list