Hallo,
ich habe n Threads, welche alle eine Variable Teilen sollen(r/w), welche anzeigt ob der I2C Bus gerade genutzt wird(Boolean).
Bisher habe ich meine variable in einem der Threads definiert und sie den anderen jeweils beim start übergeben. Funktioniert auch ganz gut, nur gibt es da eine elegantere/effizientere Lösung?
Effizienter Austausch einer Variable zwischen n Threads?
@Applepearlol: Brauchst Du an der Stelle dann nicht sowieso mindestens ein Sperrobjekt (`threading.Lock`)?
-
- User
- Beiträge: 14
- Registriert: Samstag 10. August 2013, 21:27
@BlackJack:
stimmt, hatte ich vergessen zu erwähnen.
Die jetzige Struktur für Zugriffe sieht so aus:
stimmt, hatte ich vergessen zu erwähnen.
Die jetzige Struktur für Zugriffe sieht so aus:
Code: Alles auswählen
self.lockobj.acquire()
self.master.i2c_use = 1
self.lockobj.release()
#do things with I2C Bus
self.lockobj.acquire()
self.master.i2c_use = 0
self.lockobj.release()
@Applepearlol: Das `Lock` selbst ist doch schon ein Flag. Du kannst abfragen ob es gerade benutzt wird und da wird es dann immer den gleichen Wert liefern wie Dein boole'sches Falg (was Zahlen statt `True`/`False` benutzt‽). Denn eigentlich will man ja die Operation auf dem Bus absichern und nicht so ein Flag. Und da wollte man dann auch dafür sorgen das die Sperre auf jeden Fall wieder aufgehoben wird. Mit ``with``:
Woanders kannst Du mit ``if i2c_using_object.lock.locked():`` abfragen ob der Bus gerade benutzt wird.
Der Namenszusatz `obj` bei `lockobj` ist überflüssig denn in Python ist alles was man an einen Namen binden kann ein Objekt. Das muss man deshalb nicht in jeden Namen reinschreiben.
Code: Alles auswählen
with self.lock:
# do things with I2C Bus
Der Namenszusatz `obj` bei `lockobj` ist überflüssig denn in Python ist alles was man an einen Namen binden kann ein Objekt. Das muss man deshalb nicht in jeden Namen reinschreiben.
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Python kennt Booleans mit `True` und `False`.
Und je nachdem wie deine Zugriffsmuster aussehen kannst du doch direkt das Lock benutzen, um die I2C benutzung zu regeln. Bekommt der Thread das Lock, dann darf er auch schreiben.
Dann ist das ganze auch Threadsicher, anders als momentan.
Daneben benutzt `threading.Lock` das Contextmanager Protokoll.
Zusammen:
Edit: Natuerlich war Blackjack schneller Na vielleicht hat er ja was vergessen
Und je nachdem wie deine Zugriffsmuster aussehen kannst du doch direkt das Lock benutzen, um die I2C benutzung zu regeln. Bekommt der Thread das Lock, dann darf er auch schreiben.
Dann ist das ganze auch Threadsicher, anders als momentan.
Daneben benutzt `threading.Lock` das Contextmanager Protokoll.
Zusammen:
Code: Alles auswählen
with self.lockobj:
#do things with I2C Bus
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
-
- User
- Beiträge: 14
- Registriert: Samstag 10. August 2013, 21:27
Also würde ich dann schreiben
oder
Woher weiß with denn welche Methode aufgerufen werden soll, wenn es wieder aus dem with statement rausgeht? hier wäre das nämlich self.lock.release()
Code: Alles auswählen
with self.lock.acquire():
do something
Code: Alles auswählen
with self.lock:
do something
@Applepearlol: Es muss ``with self.lock:`` heissen. Beim verlassen des ``with``-Blocks wird immer die `__exit__()`-Methode aufgerufen. Und am Anfang immer die `__enter__()`-Methode. Die müssen dann das entsprechende tun, also beispielsweise bei Sperren `aquire()` und `release()`, bei Dateien nichts und `close()`, und so weiter. Dafür ist das jeweilige Objekt selbst zuständig.