[Tutor] Using Select

dman dman@dman.ddts.net
Tue, 26 Mar 2002 12:54:14 -0600


On Tue, Mar 26, 2002 at 10:58:50AM -0600, Brian Maicke wrote:
| Howdy all,
| I have been playing around with writing a chat server
| in Python, with the eventual goal of turning it into an
| online game should I ever get ambitious enough to do so.
| 
| I currently have the code written to read the data from
| the connection and display it back to the user.  What I
| need a bit of help with is allowing multiple connections
| to do so at the same time.  Currently I plan on using
| select to allow the multiple connections.  I have a vague
| idea of how to go about using select but I am looking for
| a bit more info.  Does anyone know of a good walkthrough
| for select that they could point me to?

I don't know of a walkthrough other than the manpage and "Linux
Programming Unleashed".  (the book isn't in-depth at all, though)

I just learned how to use select myself :-).  Basically you make a
list of files that you want to read from or write to.  Then you hand
it to select and wait for it to give you back a list of the files that
are ready to be read from or written to.  Kinda like this, but I only
had one file to read from :

    f = open( "/dev/ttyS0" , "r" )
    r , _ , e = select.select( [f] , [] , [f] )
    if r :
        # the file is ready for reading
        print os.read( r , 1 ) # you may need to call r.fileno() here
    if e :
        # an exceptional condition occurred,
        # I'm really not sure what that means because neither manpage
        # nor the book explained what exceptional conditions are.
        pass

The arguments and return values are lists of file descriptors (python
allows file objects too) for the following operations :
    read
    write
    exceptional condition

| Also is there a better way to allow for the multiple connections in
| a situation like this (fork, threads)?

Forking is probably a bit heavy weight for this, unless, perhaps, each
connection will require lots of independent processing

Threading is lighter weight (and in linux, threads map to lightweight
processes) and allows sharing the address space.  Just be careful with
regards to synchronization and deadlock.


I think Sean's suggestion of starting simple select() and building up
experience as you go is a good one.  For an example you can look at
the core of Zope's ZServer -- Medusa.  It is an HTTP and FTP server
written in python, and it uses select() to achieve high performance
without the resource overhead of forking or threading.  I don't know
how its complexity compares to a threading solution, but I do have a
fair amount of experience dealing with threads (in java) and they're
not quite trivial in the real world.

HTH,
-D

-- 

The wise in heart are called discerning,
and pleasant words promote instruction.
        Proverbs 16:21