Thread per Buttonclick beenden

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.
dirty sanchez
User
Beiträge: 42
Registriert: Freitag 27. Juni 2008, 12:21

Thread per Buttonclick beenden

Beitragvon dirty sanchez » Montag 28. Juli 2008, 14:12

Hallo,

ich benutze das Modaul threading. Wie kann man einen schlafenden Thread per Button-Click beenden?
BlackJack

Beitragvon BlackJack » Montag 28. Juli 2008, 19:19

Threads kann man von "aussen" nicht beenden. Üblicherweise spendiert man Threads deshalb ein Flag, welches innerhalb des Threads regelmässig überprüft wird.
dirty sanchez
User
Beiträge: 42
Registriert: Freitag 27. Juni 2008, 12:21

Beitragvon dirty sanchez » Dienstag 29. Juli 2008, 07:31

ok danke, aber das hab ich schonmal so gelesen, jedoch dieses flag kann ja während im thread ein sleep(...) aktiv ist auch nicht überprüft werden, richtig? genau das ist mein problem! gibts wohl keine Lösung?
EyDu
User
Beiträge: 4866
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Dienstag 29. Juli 2008, 08:30

Doch, indem du den Flag in der Hauptschleife des Threads überprüfst. Dort sollte irgendwo ein Lock/eine Queue sein, welche immer dann gelöst wird, wenn eine Aktion im Thread ausgeführt werden soll. Als Aktion könntest du von außen dann "Beenden" aufrufen und der Lock wird überprüft.

Was genau hast du denn mit dem "sleep" vor, in Threads kommt man eigentlich immer ohne aus. Zur Not kannst du das Sleep mit dem Flag verbinden, so dass bei einem abgebrochenen sleep der Thread verlassen wird.
dirty sanchez
User
Beiträge: 42
Registriert: Freitag 27. Juni 2008, 12:21

Beitragvon dirty sanchez » Dienstag 29. Juli 2008, 08:42

ich hab ne Liste von Videos, diese will ich nacheinander jedoch nicht in einer playlist sondern einzeln abspielen. abhängig von der dauer des laufenden videos schläft der thread nachdem er das video gestartet hat. ist die zeit abgelaufen wacht der thread auf und startet das nächste video. jetzt brauch ich eben noch eine möglichkeit das ganze szenario mit einem button zu beenden. weiß halt nicht genau wie ich das mache. der button muss den thread ja immer beenden können egal wo ich mich in meiner schleife im thread befinde!?
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Dienstag 29. Juli 2008, 08:52

mach eben viele kleine sleeps.

Code: Alles auswählen

def littlesleep(seconds, step=0.5):
    div, r = divmod(seconds, step)
    div += bool(r)
    for _ in xrange(int(div)):
        sleep(step)
EyDu
User
Beiträge: 4866
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Dienstag 29. Juli 2008, 09:21

Dann bietet sich ein Lock mit angegebenem Timeout geradezu als Lösung an.
dirty sanchez
User
Beiträge: 42
Registriert: Freitag 27. Juni 2008, 12:21

Beitragvon dirty sanchez » Dienstag 29. Juli 2008, 09:22

danke aber versteh nicht ganz was das bringt. also wie kann ich das flag abfragen? hab doch eigentlich ne while schleife um das ganze gebilde drumherum und dann ist doch egal ob ich
z.b. sleep(35) oder
for i in range(35):
sleep(1)
schreibe. hab irgendwie bei beiden varianten kein erfolg!?
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Dienstag 29. Juli 2008, 11:09

Code: Alles auswählen

from __future__ import division
from time import sleep


def littlesleep(seconds, step=0.5):
    div, r = divmod(seconds, step)
    div += bool(r)
    for _ in xrange(int(div)):
        yield sleep(step)

if __name__ == '__main__':
    sleeper = littlesleep(5)
    breaker = False
    for _ in sleeper:
        if breaker:
            break


So. Das wirst du ja wohl noch selbst auf deinen Code übertragen können, oder?
dirty sanchez
User
Beiträge: 42
Registriert: Freitag 27. Juni 2008, 12:21

Beitragvon dirty sanchez » Dienstag 29. Juli 2008, 13:02

mir fehlt hier noch irgendwie der zusammenhang zu threading!?
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Dienstag 29. Juli 2008, 13:25

wenn ich das ganze nen Thread einbaue der sich nach Zeit x beendet sagst du bestimmt, dass du dann den Zusammenhang mit dem Knopfdruck nicht siehst..

Irgendwie musst du auch mal selbst anfangen.

Aber bitteschön:

Code: Alles auswählen

from __future__ import division
from time import sleep, time
import threading

class Sleeper(threading.Thread):

    def __init__(self, sleeptime, step=0.5):
        self.sleeptime = sleeptime
        self.step = step
        threading.Thread.__init__(self)

    def run(self):
        self.exit = False
        sleeper = littlesleep(5)
        for _ in sleeper:
            if self.exit:
                break
   



def littlesleep(seconds, step=0.5):
    div, r = divmod(seconds, step)
    div += bool(r)
    for _ in xrange(int(div)):
        yield sleep(step)

if __name__ == '__main__':
    start =  time()
    t = Sleeper(10)
    t.start()
    sleep(1)
    print time() - start
    t.exit = True
    print time () - start
   
dirty sanchez
User
Beiträge: 42
Registriert: Freitag 27. Juni 2008, 12:21

Beitragvon dirty sanchez » Dienstag 29. Juli 2008, 14:33

danke für deine hilfe und sorry dass ich mich so blöd dranstelle. ich versuch mein problem zu schildern:

Code: Alles auswählen

self.connect(self.button1, QtCore.SIGNAL("clicked()"), self.abspielen)
self.connect(self.button2, QtCore.SIGNAL("clicked()"), self.beenden)

def abspielen(self):
        threadobject = threads()
        threadobject.start()

def starten(self, video):
        arg = [pfad]
        process = subprocess.Popen(arg)

def beenden(self):
        threadobject = threads()
        threadobject.stop()

class threads(Thread, hauptklasse):
    def __init__(self):
        Thread.__init__(self)
        self.stopped = Event()

    def run(self):
        print self.stopped.isSet()
        while not self.stopped.isSet():
            for Element in liste:
                self.starten(Element)
                print 'Video wird abgespielt'
                sleep(Element.dauer)
                print 'Thread aufgewacht!'
            print 'Letztes Video abgespielt!'
            self.beenden()
        self.beenden()

    def stop(self):
        #Anhalten ausloesen
        self.stopped.set()


das stoppen funktioniert nicht. obwohl mein event ausgelöst wird und self.stopped = True ist. nachdem der thread aufgewacht ist ist self.stopped wieder False , ka warum. hoffe das hilft weiter um mir weiterzuhelfen.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Dienstag 29. Juli 2008, 14:35

Ich seh schon, du hast meinen Code nicht ernsthaft angeschaut...

Das littlesleep schrieb ich nicht ohne Grund...argh.
dirty sanchez
User
Beiträge: 42
Registriert: Freitag 27. Juni 2008, 12:21

Beitragvon dirty sanchez » Dienstag 29. Juli 2008, 14:41

tut mir leid konnte deinen code nicht so ganz auf mein problem beziehen. liegt das problem also am sleep? normal müsste doch dann spätestens nach dem sleep der thread beendet werden oder?
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Dienstag 29. Juli 2008, 15:00

probiers doch erstmal ohne Gui.

Teste an meinem Beispiel rum und teste als Vergleich dazu nen Thread, der anstatt des `for _ in littlesleep(n)` nen normales sleep(n) benutzt.

Und poste bitte Code, der für sich stehend ausführbar ist und dein Problem zeigt.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot], egon11, Whitie