Synchronous signals vs. robust code

Mark Mitchell mark at codesourcery.com
Mon Feb 18 13:34:07 EST 2002


--On Monday, February 18, 2002 05:34:14 PM +0000 Toby Dickenson 
<tdickenson at devmail.geminidataloggers.co.uk> wrote:

> (reply posted, and cc to Mark)

Thanks for CC'ing me; I'm not on the list, so up until now I've
been keeping up with follow-ups by reading the list archives.

> No major damage is done if the exception ends up terminating this
> python process,

Yes.  In almost any environment, one must be willing to accept that
one's process may be summarily killed by the operating system at any
time, or that the power may go off...

> or if the exception is only caught after sufficient
> objects have been destroyed that it has lost all reference counts on
> the crucial file objects.

I'm don't think it's a critical point, but this won't happen here;
Python won't close the pipe when the descriptors are no longer referenced.
There's no object involved and no __del__ method to be invoked; those
file descriptors are just numbers.  So, no, we can't just let the
exception escape far enough and then rely on GC to clean up the
descriptors.

Abstracting away from pipes, the point is that when one writes:

  try:
    f()
  finally:
    g()

one intends that one of two things will happen:

1. f() will not terminate, either because it runs forever, because it
   calls "exec", or because the process is killed, or ...

2. f() will eventually terminate, either by throwing an exception or
   by returning, in which case "g()" will be executed.

In C++, and I believe in Java, and in most other languages with similar
features, those are precisely the two outcomes that can occur.

>> One solution, of course, is to make sure that the signal-handlers do
>> not throw exceptions.  But that's not a reasonable solution in library
>> code; the library can't go around deciding what signal handlers should
>> be doing.
>
> A library working to those standards is already in trouble without
> introducing anything so tricky as a signal. In python almost any
> operation can potentially raise an exception: function calls, slices,
> and even assignments to globals or class attributes may involve memory
> allocation which may fail.

It is true that out-of-memory errors can occur almost anywhere, and
that they are hard to handle.

However, robustness is a matter of degree: some applications are robust
in the presence of erroneous input, some in the presence of
unavailable resources, some in the presence of hardware failure, and
so forth.

So, leaving aside *other* ways in which it may be hard to write robust
Python programs, I'd like to refocus on signals.

Is it possible to write Python programs that are robust in the presence
of signals, in the sense that I originally indicated?

If not, would people consider adding language support to provide this
robustness, so that Python can be used in applications that require
that level of robustness?

(Footnote: at least one interpreted language -- Scheme48 -- handles
signals by making them *more* synchronous than Python; the application
must explicitly poll for signals when it wants to handle them.  That
avoids the signal-safety issues I've raised, at the expense of making
it difficult to respond to signals in a timely fashion.)

-- 
Mark Mitchell                mark at codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com




More information about the Python-list mailing list