Re: Async and single threading sockets in SBCL
- From: Marcin 'Qrczak' Kowalczyk <qrczak@xxxxxxxxxx>
- Date: Fri, 22 Apr 2005 12:44:18 +0200
pkhuong@xxxxxxxxx (Paul Khuong) writes:
> I'd take a look at this document: http://www.lisp-p.org/tcpmux/, which
> describes a single threaded server (with multiple connections) in
> CLISP. Corresponding/close enough I/O functions should exist for SBCL
> too.
> "I think threads are over-used. They are too often used at the expense
> of simplicity & maintainability. In fact, threads are often used at
> the expense of correctness.
I disagree.
> A single thread can achieve most of the performance you can achieve
> with multiple threads unless you have multiple CPUs and you know what
> you are doing with multiple-threads. Multiple CPUs are fairly common
> these days, but most humans can't do a very good job with multiple
> threads.
This is a separate issue: it may look as threads to the programmer yet
be implemented using a single OS thread. But I believe threads are
usually clearer to a programmer than manual context switching.
Here isa part of tcpmux implementation of a function which sends a
help text in the response to the "help" request:
(defmethod done-writing ((self help))
(cond ((lst self)
;; There's something to write, so we queue it & an ASCII
;; CR LF pair after it.
(enqueue-write self (pop (lst self)))
(enqueue-write self '(13 10)))
(t
;; There's nothing more to write, so we bug out.
(remove-connection self :close t)))
self)
Note that it materializes the current continuation (which in this case
corresponds to a list of lines to be written). This approach is awful
for a complex control flow of a single connection. You cannot call a
function which writes something to a socket. Instead you must store
the state in an object and return, and you will be called back when
the write completes.
Similarly for reading. You don't call a function, but your class
provides an implementation of the generic function nread, which is
called when the next character is available. This forces to dispatch
all actions done after reading from a signle point of code.
> I've written single-threaded servers that support multiple connections
> & have good performance, but until now, they've all been owned by my
> employers. I wanted to implement such a server that was free
> software4.1 as proof that single-threaded network servers work just
> fine. So my second requirement was ``Use a single thread because I
> want to demonstrate that it can be done with a single thread''. "
Looking at the implementation of tcpmux, it processes a single
character at a time between returning to the event loop. One iteration
of an event loop makes work proportional to the number of active
connections, in particular it conses 3 new lists of that size. Inside
a single connection, a buffer of bytes to write is represented as a
list of integers, which is repeatedly appended at the end.
I don't believe that this implementation is efficient for non-toy
usages. It could be written with much better quality even while
keeping this style. And as I said above, IMHO this style is awful.
--
__("< Marcin Kowalczyk
\__/ qrczak@xxxxxxxxxx
^^ http://qrnik.knm.org.pl/~qrczak/
.
- References:
- Async and single threading sockets in SBCL
- From: Steve Smith
- Re: Async and single threading sockets in SBCL
- From: Steve Smith
- Re: Async and single threading sockets in SBCL
- From: Paul Khuong
- Async and single threading sockets in SBCL
- Prev by Date: Re: My first macro
- Next by Date: Re: Creating personalized streams
- Previous by thread: Re: Async and single threading sockets in SBCL
- Next by thread: Re: Async and single threading sockets in SBCL
- Index(es):
Relevant Pages
|