Will python ever have signalhandlers in threads?

Antoon Pardon apardon at forel.vub.ac.be
Mon Nov 15 12:44:31 CET 2004


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.


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


-- 
Antoon Pardon



More information about the Python-list mailing list