Seite 1 von 1

conditions + wait

Verfasst: Sonntag 20. September 2009, 17:28
von maxwell
Hallo Forum,

kurze Frage, was macht die wait-Methode?
Schickt diese den thread schlafen oder durchläuft sie eine while schleife?
Kann man einen thread gezielt schlafen legen?

Viele Grüße + wie immer vielen Dank im voraus,

chris

Verfasst: Sonntag 20. September 2009, 17:40
von HWK
Aus threading.py:

Code: Alles auswählen

    def wait(self, timeout=None):
        if not self._is_owned():
            raise RuntimeError("cannot wait on un-aquired lock")
        waiter = _allocate_lock()
        waiter.acquire()
        self.__waiters.append(waiter)
        saved_state = self._release_save()
        try:    # restore state no matter what (e.g., KeyboardInterrupt)
            if timeout is None:
                waiter.acquire()
                if __debug__:
                    self._note("%s.wait(): got it", self)
            else:
                # 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).
                endtime = _time() + timeout
                delay = 0.0005 # 500 us -> initial delay of 1 ms
                while True:
                    gotit = waiter.acquire(0)
                    if gotit:
                        break
                    remaining = endtime - _time()
                    if remaining <= 0:
                        break
                    delay = min(delay * 2, remaining, .05)
                    _sleep(delay)
                if not gotit:
                    if __debug__:
                        self._note("%s.wait(%s): timed out", self, timeout)
                    try:
                        self.__waiters.remove(waiter)
                    except ValueError:
                        pass
                else:
                    if __debug__:
                        self._note("%s.wait(%s): got it", self, timeout)
        finally:
            self._acquire_restore(saved_state)
MfG
HWK

Verfasst: Sonntag 20. September 2009, 18:02
von maxwell
Ok, Danke HWK...

Ich hatte gestern schon mal in die sourcen geschaut, war aber schon zu müde.

Meine Frage galt folgenden Problem. Wenn ich den folgenden Code ohne ein Condition-Object ausstatte und wait() selbst abhandle, so stellt sich eine wesentlich schlechtere Performance ein. Ich dachte daher an die 'while' - Schleife in der wait() Methode. Deshalb meine Frage nach der Handhabe in der Condition.

Code: Alles auswählen

from threading import*
from time import*
from random import*

INIT = 0x01
READY = 0x02
WAIT = 0x03

class t0(Thread): pass
class t1(t0):
    def __init__(self, num=2, tasks=[]):
        t0.__init__(self)
        self.threads = []
        self.num = num
        self.tasks = tasks
    
    def start(self):     
        for t in range(self.num):
            self.threads.append(t2())
        for t in self.threads:
            print "starte thread %s" % t.getName()
            t.start()
            while t.mode == INIT:
                print 'warte auf bereitschaft'
                sleep(0.1)

    def run(self):
        self.start()
        while True:
            pass # verteile tasks auf die threads

    def terminate(self):
        for t in self.threads:
            while t.task:
                sleep(.1)
            t.term = 1 
            t.notify()
            t.join()          

class t2(t0):
    def __init__(self):
        t0.__init__(self)    
        self.term = 0
        self.task = None
        self.mode = INIT

    def notify(self):
        self.mode = READY

    def wait(self):
        self.mode = WAIT
        while self.mode == WAIT:
            pass

    def run(self):
        self.mode = READY
        print 'warte und bin betriebsbereit  %s' % self.getName()
        while not self.term:
            if not self.task:
                self.wait()

if __name__ == '__main__':
    try:
        m = t1(5)
        m.start()
        input()
    except KeyboardInterrupt:
        m.terminate() 
Viele Grüße,

Chris

Verfasst: Sonntag 20. September 2009, 18:33
von BlackJack
@maxwell: Zum Verteilen von Tasks auf Threads würde ich erst einmal `Queue.Queue` anschauen, bevor ich das Rad neu erfinde.

Verfasst: Sonntag 20. September 2009, 18:50
von maxwell
@blackjack

kann man machen. Muss man aber nicht! :P Gleichwohl das kein Prod. code sondern nur ein Test code ist. Es galt ja hier sicherzustellen, dass der thread wartet bis "x" eintritt. Aber dennoch vielen Dank für Deinen Hinweis.

Viele Grüße + einen schönen Sonntagabend allen...
Chris