[Python-Dev] Problem with signals in a single threaded application

"Martin v. Löwis" martin at v.loewis.de
Mon Jan 29 08:52:12 CET 2007


Greg Ewing schrieb:
> Correct me if I'm wrong, but what I got from the OP
> was that the current method does

Ok, I'm correcting you: This is not what the current
method does:

> 
>    if (is_tripped) {
>      for each signal {
>        if the signal has occurred, call its handler
>      }
>      is_tripped = 0;
>    }

Instead, the current method does this:

if (!is_tripped)
  return;
for each signal {
  if the signal has occurred, call its handler
}
is_tripped = 0

> and the problem is that any setting of is_tripped that
> occurs in the midst of calling the handlers gets
> wiped out at the end.
> 
> Changing this to
> 
>    while (is_tripped) {
>      for each signal {
>        if the signal has occurred, call its handler
>      }
>      is_tripped = 0;
>    }

My proposal (wrap the for loop with another is_tripped
looo) would literally give

  if (!is_tripped)
    return;
  while(is_tripped) {
    for each signal {
       if the signal has occurred, call its handler
    }
 }
 is_tripped = 0

Of course, that doesn't make much sense as it gives
an infinite loop. You need to clear is_tripped somewhere,
and I thought clearing it before the for loop would
work

  if (!is_tripped)
    return;
  while(is_tripped) {
    is_tripped = 0;
    for each signal {
       if the signal has occurred, call its handler
    }
 }

> If you really care, you can make that a while instead
> of an if so that you don't have to wait until the next
> CheckSignals. But if the signal had arrived a few
> microseconds later you'd have to do that anyway, so
> I don't see it as a big deal.

Sure. However, it's not that the signal would occur
"randomly" a few microseconds later, but instead
occurs *in* the signal handler.

I think Python currently has some "guarantee" that
a signal handler will be called quickly: either the
signal gets tripped in a blocking system call, which
ought to abort the system call, or the interpreter
is executing byte codes, when it will check for
signals every nth instruction.

A signal can get delayed significantly if the
interpreter makes a blocking system call before
handling the signal. I think this can happen
even today (if there is a blocking call between
the signal and the nth instruction, the signal
may still get delayed). However, in this specific
case, I think the chance that that the signal
gets delayed is high, and the case can be easily
implemented to avoid that risk.

Regards,
Martin


More information about the Python-Dev mailing list