event loops and Python?

Donn Cave donn at u.washington.edu
Tue Mar 14 13:01:04 EST 2000


Quoth kragen at dnaco.net (Kragen Sitaker):
[re my mention of asyncore]
| Nobody had yet mentioned asyncore in this thread.  Thanks!  That's
| exactly the kind of thing I was looking for.
|
| Asyncore doesn't look perfect from an efficiency point of view, but it
| looks like it might be simpler for a client to use than a raw
| event-loop API.

I've never used it, honestly, that was a reference to someone else
who actually did mention it (hard to follow a small thread for a
couple of days on this newsgroup, sorting through ca. 100 posts a day!)
It's a hard problem domain to really rule in, too diverse for a single
solution to easily solve everyone's problems, but at worst it may have
some code you can steal.

|>| Another is that handling signals safely in Perl is tough, and I
|>| assume the same thing is true of Python.
|>
|> True, and I say good riddance.  Signals are easier to use in C, but
|> are really appropriate for only low level stuff, in my opinion -
|> for example from a software engineering point of view, try to get your
|> two pieces of code to cooperate over signals, or even protect themselves
|> from each other's use of signals.
|
| In Unix, there are things that can only be done in a non-blocking
| fashion by handling signals:  SIGCHLD when a child process dies, for
| instance.  And it's probably a good idea to handle SIGTERM and SIGWINCH.
|
| Treating those signals as events like any other can simplify your life
| drastically.
|
| (There are cases where you really do need interrupt-style signals, but
| in an event-loop-based application with quick event-handlers, SICHLD,
| SIGTERM, and SIGWINCH are not among them.)

SIGCHLD is the most useless signal there is, pure bad news.  I would
heartily encourage Python programmers in particular to steer clear of
it, but you do what you want.  It's unreliable, it runs into conflicts
with library software that forks and may or may not use SIGCHLD, and
it may interrupt slow system calls, causing an exception that's difficult
to handle properly at the application level.  Even in C, when I see a
SIGCHLD handler I smell trouble.

...
| I'll be writing a mailer.  I'll spawn off child processes to edit
| mail.  wait() is not an option.  Handing SIGCHLD is necessary.

Someone recently proposed here that you could give the child process
the write end of a pipe, and watch its read end in your select loop.
When it's readable, you have reason to believe it just closed due to
process exit.  (Remember to close the write end in the parent, after
the child forks.)

It happens I'm writing this in a vim process, spawned by my Python
news reader.  This is on BeOS, so there are threads all over the
place and I actually have a thread just to wait for the vim process
and post a message when it exits.  The threadless UNIX version of
that design would be a bit more expensive, but really inconsequentially
so - I mean, parent<fork<fork+exec is cheaper than a shell wrapper
around vim (parent<fork+exec<fork+exec) and no one would blink an
eye at that.

The third alternative I can suggest is to poll - time out of select
two or three times a second when there's an outstanding process.
The overhead is negligible, and eventually you'll find that you have
other business to take care of here anyway.

Write nothing in C.

	Donn Cave, donn at u.washington.edu



More information about the Python-list mailing list