conditions + wait

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
maxwell
User
Beiträge: 69
Registriert: Samstag 11. Juli 2009, 15:36
Wohnort: am Fernsehturm in B.

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
be or not to be
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

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
maxwell
User
Beiträge: 69
Registriert: Samstag 11. Juli 2009, 15:36
Wohnort: am Fernsehturm in B.

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
be or not to be
BlackJack

@maxwell: Zum Verteilen von Tasks auf Threads würde ich erst einmal `Queue.Queue` anschauen, bevor ich das Rad neu erfinde.
maxwell
User
Beiträge: 69
Registriert: Samstag 11. Juli 2009, 15:36
Wohnort: am Fernsehturm in B.

@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
be or not to be
Antworten