Will python ever have signalhandlers in threads?

Bengt Richter bokr at oz.net
Mon Nov 15 15:25:12 EST 2004


On 15 Nov 2004 11:44:31 GMT, Antoon Pardon <apardon at forel.vub.ac.be> wrote:

>Op 2004-11-15, Peter Hansen schreef <peter at engcorp.com>:
>> Antoon Pardon wrote:
>>> AFAIU the Queue module doesn't block on a full/empty queue when
>>> a timeout is specified but goes in a loop sleeping and periodically
>>> checking whether place/items are available. With signals that
>>> can be sent to a thread the queue could just set an alarm and
>>> then block as if no timeout value was set and either unblock
>>> when place/items are available or get signalled when the timeout
>>> period is over.
>>
>> I'm fairly sure that the Queue uses an internal Event
>> (or REvent?) to signal when space or a new item is
>> available, so I believe your description (and possibly
>> conclusion) above is wrong.  There should be no
>> "periodical check", as that would imply polling.  Check
>> the source if you're interested.
>
>I did check the source, I just didn't study it carefully
>and got my understanding mostly from the comments.
>But anyway here is the relevant part and IMO we have
>a polling loop here.
It looks like you are right, at least on NT, where it is a shame,
since thread_nt.h only uses WaitForSingleObject with INFINITE timeout
specified, and it would seem the ideal timeout support API could be provided.
Maybe the lock acquire method could have an optional keyword arg timeout=floatingseconds,
and for NT that could be converted to milliseconds and used to wait for the mutex
with a non-inifinite wait. But it's platform dependent what low level OS support
there is for locks with timeouts. However, a win32 solution should benefit
a fair proportion of users, if many windows users do threading.

>
>
>class Queue:
>
>  ...
>
>  def get(self, block=True, timeout=None):
>    """Remove and return an item from the queue.
>
>    If optional args 'block' is true and 'timeout' is None (the default),
>    block if necessary until an item is available. If 'timeout' is
>    a positive number, it blocks at most 'timeout' seconds and raises
>    the Empty exception if no item was available within that time.
>    Otherwise ('block' is false), return an item if one is immediately
>    available, else raise the Empty exception ('timeout' is ignored
>    in that case).
>    """
>    if block:
>      if timeout is None:
>        # blocking, w/o timeout, i.e. forever
>        self.esema.acquire()
>      elif timeout >= 0:
>        # waiting max. 'timeout' seconds.
>        # this code snipped is from threading.py: _Event.wait():
>        # Balancing act:  We can't afford a pure busy loop, so
>        # we
>        # have to sleep; but if we sleep the whole timeout time,
>        # we'll be unresponsive.  The scheme here sleeps very
>        # little at first, longer as time goes on, but never
>        # longer
>        # than 20 times per second (or the timeout time
>        # remaining).
>        delay = 0.0005 # 500 us -> initial delay of 1 ms
>        endtime = _time() + timeout
>        while 1:
>          if self.esema.acquire(0):
>            break
>          remaining = endtime - _time()
>          if remaining <= 0:  #time is over and no element arrived
>            raise Empty
>          delay = min(delay * 2, remaining, .05)
>          _sleep(delay)       #reduce CPU usage by using a sleep
>

So, it would seem this kind of thing could be hidden in platform-specific
files where it was really necessary. Probably the people who can do it are
too busy ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list