threading

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
KuniBert
User
Beiträge: 11
Registriert: Mittwoch 4. März 2015, 19:41

Hallo,
ich möchte einen Thread als object anlegen und diesen während meines Programms starten und der Programmablauf soll weiter gehen.

Code: Alles auswählen

import threading
import time
import RPi.GPIO as GPIO

class ampel(threading.Thread):
    def run(self, color):
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(17, GPIO.OUT)
        while color == "green":
            GPIO.output(17, 1)

x = 0
while x< 15:
    ampel = ampel()
    ampel.run("green")
    print x
    x +=1
    time.sleep(2)
Wenn ich das Programm starte wird die run() Methode durchgeführt (LED leuchtet) jedoch läuft die Schleife nicht weiter. Wieso ist das so? Ich dachte wenn ich die Methode im Thread starte dann ist das ein Programmablauf nebenbei!? Wie kann ich die Schleife schreiben damit sie weiter läuft?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Du startest den Thread nicht, dafür musst du .start() statt .run() aufrufen.
KuniBert
User
Beiträge: 11
Registriert: Mittwoch 4. März 2015, 19:41

wenn ich .run() gegen .start(9 austausche klappt es auch nicht. :( Das Programm bleibt immer hängen.
BlackJack

@KuniBert: Was meinst Du mit ”hängen”? Das Programm endet erst wenn alle „daemon”-Threads zuende sind. Du müsstest also dafür sorgen das die `run()`-Methode an ihr Ende kommt, oder den Thread vor dem starten zu einem „non-daemon”-Thread machen. Dafür haben `Thread`-Objecte ein `daemon`-Attribut.
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@KuniBert: Deine Probleme kommen nicht von Multithreading, sondern daher, dass dein Programm fehlerhaft ist. An Multithreading würde ich mich erst heranwagen, wenn ich alles andere einigermaßen beherrsche.

So einen Fehler zB.:

Code: Alles auswählen

>>> class ampel:
...    pass
...
>>> print(ampel)
<class '__main__.ampel'>
>>> ampel = ampel()
>>> print(ampel)
<__main__.ampel object at 0xb6f7b16c>
>>> ampel = ampel()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'ampel' object is not callable
Außerdem frage ich mich, warum Anfänger sich selber das Leben immer so schwer machen. Vergleiche mal:

Code: Alles auswählen

>>> x = 0
>>> while x < 5:
...     print(x)
...     x += 1
...
0
1
2
3
4
>>> for x in range(5):
...     print(x)
...
0
1
2
3
4
Nicht nur sind es in der zweiten Variante nur halb soviele Zeilen Code, es gibt auch weniger Stellen, wo man etwas verkehrt machen kann und damit weniger Stellen, die man sich anschauen muss, wenn man etwas verkehrt gemacht hat.

Und dann das, dass run außer self eben keine Parameter erwartet:

Code: Alles auswählen

>>> import threading
>>> class ampel(threading.Thread):
...     def run(self, bla):
...         pass
...
>>> ampel().start()
>>> Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
    self.run()
TypeError: run() missing 1 required positional argument: 'bla'
Zuletzt geändert von pillmuncher am Samstag 21. März 2015, 22:18, insgesamt 1-mal geändert.
In specifications, Murphy's Law supersedes Ohm's.
BlackJack

Ergänzend: Wenn man in der Subklasse nur `run()` implementiert oder nur `run()` und `__init__()` um der `run()` Werte mitzugeben, dann ist die Klasse in der Regel überflüssig und man kann einfach eine Funktion schreiben und die dem `Thread`-Objekt als `target`-Argument übergeben, und Argumente als `args`-Argument.
Antworten