threading.Timer Problem

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
t0m

Hallo,

ich bin ziemlich neu in Python und möchte nun alle X Sekunden eine bestimmte Funktion aufrufen. Das wollte ich mit threading.Timer machen.. Aber irgendwie bleibt das Programm nach den X Sekunden hängen, als würde eine Endlosschleife gestartet werden!!

Hier der Code welcher einfach nicht funktionieren will:

Code: Alles auswählen

import threading

def Test():
    print "OK"

T = threading.Timer(5, Test)
T.start()
Oder gibt es eine andere Möglichkeit die ebenfalls diesen Job erledigt?

mfg,
Tom[/code]
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi t0m,

mit threading.Timer(x, func) wird die Funktion func nach x Sekunden einmal aufgerufen!

Code: Alles auswählen

def Test():
    global T
    print "OK"
    T = threading.Timer(5, Test)
    T.start()

Test()
hier ist es ausnahmsweise vorteilhaft, T als globale Variable zu verwenden um mittels T.cancel() die Ausführung stoppen zu können.


Gruß

Dookie
Gast

Hi Dookie,

danke für die Hilfe. Aber das Programm bleibt trotzdem hängen! Ich bekomm zwar das erste "OK" ausgegeben aber das wars auch..

mfg,
t0m
t0m

hmmm
anscheinend funktioniert threading.Timer nicht wenn ich den Code direkt in IDLE ausführe...

In der normalen Python-Shell geht der Code ohne Probleme! Merkwürdig..

mfg,
FiRe
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Das glaub ich eher weniger, da es bei mir ohne Probleme funktioniert... was meinst du mit hängen bleiben direkt? Reagiert er noch auf Tastatureingaben oder reagiert er gar nicht mehr?
DER Olf
User
Beiträge: 283
Registriert: Mittwoch 24. Dezember 2003, 19:32

doch....IDLE is sone sache

dann wirst du es wohl nur in der Shell ausführen können.

mfg Olf
RainBowBender
User
Beiträge: 53
Registriert: Dienstag 6. April 2004, 10:33

in "Python ge-packt" steht, dass man Python scripte mit Threads nicht unter IDLE ausführen sollte, wegen solchen Abstürzen. Insbesondere wird vor Windows in Verbindung mit IDLE und Threads gewarnt.
DER Olf
User
Beiträge: 283
Registriert: Mittwoch 24. Dezember 2003, 19:32

vor
Windows + IDLE
würde ich sowieso warnen :lol:

mfg

Olf
studi
User
Beiträge: 25
Registriert: Montag 2. Juni 2008, 22:59

Hey Milan wie machst du das mit Your IP is XXX..... und so weiter und so fort.
Ich habe angs Big Brother is watching me :shock: :shock: :shock:
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

studi hat geschrieben:Hey Milan wie machst du das mit Your IP is XXX..... und so weiter und so fort.
Ich habe angs Big Brother is watching me :shock: :shock: :shock:
Deine IP sieht zwangsläufig jeder Webserver von dem du was abruft und damit sieht man auch den ISP. Irgendwohin muss der die Daten ja senden. Und damit dir auch die richtige Website gezeigt wird, sendet dein Browser seine Version, die Spracheinstellungen und das Betriebssystem mit.

Letztere Sachen kann man beim Firefox unterdrücken, ist aber nicht so sinnvoll ;)
studi
User
Beiträge: 25
Registriert: Montag 2. Juni 2008, 22:59

Hallo an alle.
Im rahmen eines Projekts versuche ich ein Diagnose Programm fuer Industrieroboter zu schreiben. Die Robotersteuerung liefert int Werte. Um
das arme Ding nicht staendig laufen lassen zu müssen will ich die Sensorwerte simulativ erzeugen. Das Prog. soll also jede 5 Sekunden paar Werte liefern. Ich hab's wie oben versucht und folgendes bekommen:

Code: Alles auswählen

import random
import threading
from timeit import Timer

class roboterzelle :
    def schrauber (number):
        zufall = []
        for i in range (number):
            wert = random.randrange(0,19999)
            zufall.append(wert)
        return zufall
    def hexopoth (number):
        zufall = []
        for i in range (number):
            wert = random.randrange(0,19999)
            zufall.append(wert)
        return zufall
    def hydraulik (number):
        zufall = []
        for i in range (number):
            wert = random.randrange(0,19999)
            zufall.append(wert)
        return zufall
    t = threading.Timer(5.0 , schrauber(10))
    t = threading.Timer(5.0 , hexopoth(10))
    t = threading.Timer(5.0 , hydraulik(10))
    t.start()

    print "Schrauberwerte sind = " , schrauber(10)
    print "Hexopothwerte sind = " , hexopoth (10)
    print "Hydraulikwerte sind = " , hexopoth (10)
Fehlermeldung:

Code: Alles auswählen

IDLE 1.2      
>>> ================================ RESTART ================================
>>> 

>>> Exception in thread Thread-3:
Traceback (most recent call last):
  File "C:\Programme\Python25\lib\threading.py", line 460, in __bootstrap
    self.run()
  File "C:\Programme\Python25\lib\threading.py", line 625, in run
    self.function(*self.args, **self.kwargs)
TypeError: 'list' object is not callable
Mein problem ist ich bin auf IDLE und Windows zwangsweise gebunden da ich im Uni Netzwerk keine Programme instalieren darf :evil:
Hat jemand eine Idee wie man das Problem lösen könnte, bin für jede Hilfe dankbar. Bitte hilft mir. :)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@studi: Da wo IDLE läuft ist auch irgendwo ein Python-Interpreter für die Konsole dabei! Ich zitiere mal aus der "idle.bat":
python.exe ./Lib/idlelib/idle.py
Und schau doch bitte noch mal ins Tutorial (besser vielleicht ein Buch über OOP), da fehlen überall die "self" in den Methoden. Und der Fehler liegt auch nicht an den Threads, sondern am Start der Threads. Du übergibst diesen keine Funktion, sonder rufst diese auf. Hast du dir die Fehlermeldung eigentlich mal angeschaut?

Und warum machen deine Methoden eigentlich alle das selbe :? ?
studi
User
Beiträge: 25
Registriert: Montag 2. Juni 2008, 22:59

Ja klar ist der Python-Interpreter vorhanden, es ging blos darum das die Fehlermeldung, (gans oben im Thema) auf die schwaechen von Windows und IDLE geschoben wurde, deshalb habe ich darauf hingewiesen, dass ich mit IDLE arbeiten muss.

Ja ich muss mal wirklich im Tutorial besser nachschauen, wer sucht der findet. :wink: Aus der Dokumentation geht ja hervor, dass die Funktion

Code: Alles auswählen

threading.Timer(5.0 , schrauber(10))
beliebige Methoden nach einer bestimmten Zeit aufruft, da muss ich doch eigentlich gar nicht uebergeben, oder? :?

Danke fuer die Tips, ich schau mal und melde mich dann wieder.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

studi hat geschrieben:Ja klar ist der Python-Interpreter vorhanden, es ging blos darum das die Fehlermeldung, (gans oben im Thema) auf die schwaechen von Windows und IDLE geschoben wurde, deshalb habe ich darauf hingewiesen, dass ich mit IDLE arbeiten muss.
EyDu hat dir ja gezeigt, dass du das nicht musst. Du kannst Code in IDLE schreiben und sie mit dem Interpreter ausführen.
studi hat geschrieben:Ja ich muss mal wirklich im Tutorial besser nachschauen, wer sucht der findet. :wink: Aus der Dokumentation geht ja hervor, dass die Funktion

Code: Alles auswählen

threading.Timer(5.0 , schrauber(10))
beliebige Methoden nach einer bestimmten Zeit aufruft, da muss ich doch eigentlich gar nicht uebergeben, oder? :?
Du übergibst aber da keine Funktion als Argument sondern eine Liste - genau die die bei ``schrauber(10)`` rauskommt. Probiers selbst mal im interaktiven Interpreter.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
studi
User
Beiträge: 25
Registriert: Montag 2. Juni 2008, 22:59

Du übergibst aber da keine Funktion als Argument sondern eine Liste - genau die die bei ``schrauber(10)``

Ja Leonidas du hast ja wie gewohnt recht. Ich muss lernen wie ein Informatiker zu denken. "Man kann sich ein buch kaufen, aber kein Wissen"

Jetz habe ich folgendes: Generiert wenigstens jede 2 Sekunden eine Liste :D

Code: Alles auswählen

import random
import threading
from timeit import Timer

def schrauber ():
    zufall = []
    number = 5
    global t
    for i in range (number):
        wert = random.randrange(0,19999)
        zufall.append (wert)
    t = threading.Timer(2.0 , schrauber)
    t.start()
    print zufall
    return zufall

zufall = schrauber()
print "Zufall ist" ,zufall

Code: Alles auswählen

[261, 19039, 1441, 1039, 9061]
Zufall ist [261, 19039, 1441, 1039, 9061]
[1726, 19229, 2464, 4964, 16206]
[1082, 18507, 9268, 16838, 10484]
Was ich nicht verstehe, die Funktion schrauber wird ja jede 2-te Sekunde aufgerufen gibt aber die Liste nur ein mal zurück. :?
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Wäre es nicht auch seltsam wenn nach 2 Sekunden deine quasi Mainfunktion nochmal aufgerufen werden würde?
Nur deine Funktion wird noch einmal aufgerufen, mehr nicht.
BlackJack

@studi: *Du* rufst die Funktion nur einmal auf. Alle zwei Sekunden wird dann ein Thread gestartet, der die Funktion aufruft, aber Threads haben 1. keinen Rückgabewert und 2. wo sollte das Ergebnis auch landen!?

2. ist so ein bisschen das Problem was ich sehe: Wie willst Du auf die Werte zugreifen? Du sagst alle paar Sekunden sollen zufällige Werte erzeugt werden, aber mit denen muss doch auch irgend etwas passieren!?
studi
User
Beiträge: 25
Registriert: Montag 2. Juni 2008, 22:59

Guten Abend.
2. wo sollte das Ergebnis auch landen!?
Das Ergebnis sollte urspruenglich in einer Liste gespeichert werden, habe es auch gemacht mit einer schleife. Na ja aufjeden Fall passt es mir jetzt so. Die Werte müssen halt jetzt mit hilfe einer Normalverteilung "begradigt" werden. :shock:
Das Ziel ist ein Analyse Programm das anomalien (Fehler) erkennt und diese dann dem Benutzer meldet, hier z. B. das der Schrauber halt kaputt ist. :D

Danke fuer eure Hilfe, ich schau dann mal weiter. :wink:
Zuletzt geändert von studi am Dienstag 10. Juni 2008, 15:29, insgesamt 1-mal geändert.
BlackJack

Mit Feld meinst Du wahrscheinlich Liste. Die dürften zwar in der CPython-Implementierung "thread safe" sein, aber ich würde zur Kommunikation zwischen Threads doch eher eine `Queue.Queue` empfehlen.

Oder sollen immer nur `number` Werte gleichzeitig verfügbar sein und die alten Werte verworfen werden? Kannst Du die Werte eventuell auch erst bei der Anforderung erzeugen lassen statt ständig im Hintergrund neue Zufallszahlen zu erzeugen?
Antworten