[FIXED] Schnelle IO-Operationen in einem separaten Thread

Ausgabe

Ich habe eine Reihe von Instrumenten, mit denen mein Programm kommuniziert, und ich möchte die Kommunikation in einen separaten Thread stellen.

Der IO ist ziemlich langsam (~ 100 ms pro Element pro Instrument), und ich muss die daraus resultierenden Werte in einem gemeinsam genutzten Array (der letzten N Werte) aufzeichnen und in einer Datei speichern, wobei wiederholte Messungen so schnell wie möglich durchgeführt werden . Einige Instrumente „formulieren“ nur langsam eine Antwort, daher könnten einige Messwerte gleichzeitig durchgeführt werden, aber die Messwerte müssen ungefähr synchronisiert werden (dh 1 Zeitstempel pro Messwertreihe).

Ich möchte, dass dies alles in einem oder mehreren separaten Threads ausgeführt wird, damit das Timing nicht durch Berechnungen usw. im Hauptthread unterbrochen werden kann, aber der Hauptthread sollte auf das Array zugreifen können.

Idealerweise sollte ich in der Lage sein, einige auszuführen daq.start()und es geht ohne weitere Interaktion los.

Was ist der “pythonische” Weg, dies zu tun? Ich habe über Asyncio, Threading und Multiprocessing gelesen und es ist mir unklar, was angemessen ist.

In C ++ hätte ich Thread1 gestartet, der nur Messungen sequentiell in ein Cache-Array aufzeichnen würde. Thread2 würde diesen Cache in das gemeinsam genutzte Hauptarray leeren, wann immer er eine Sperre erhalten könnte. Gleichzeitig würde es das in die Ausgabedatei schreiben. Durch die Verfolgung der gelesenen Indexbereiche wären Sperrkonflikte selten (aber vor allem würden sie die DAQ nicht unterbrechen, wenn sie auftreten).

Lösung

Die richtige Antwort hier ist Threads, dies ist keine Meinung.

Die Kommunikation mit der Hardware erfolgt über in DLLs implementierte Treiber, und wenn Python eine DLL aufruft, wird die GIL gelöscht, sodass Threads im Hintergrund mit so wenig Aufwand wie möglich auf dem Python-Interpreter selbst ausgeführt werden können.

Es sollte eine ordnungsgemäße Synchronisierung durchgeführt werden, die Thread-Sperren enthält, wenn das Schreiben in Dateien mit den Threads erfolgt, aber auch beim Schreiben in Dateien werden die Threads die GIL löschen und sie haben immer noch wenig bis gar keinen Overhead für Ihren Python-Interpreter.

Beides gilt nicht für asyncio, das für asynchrone Netzwerke und nicht für Hardware entwickelt wurde.

Für die Implementierung ist ein Threadpool normalerweise der pythonischste Weg, dies zu tun. Sie erzeugen einfach so viele Arbeiter wie die Anzahl der Instrumente, mit denen Sie sich verbinden, und lassen sie ihre Arbeit erledigen.

Da Sie keine der asyncio-Funktionen verwenden, sollten Sie multiprocesing.threadpool mit apply_asyncor imap_unorderedund den Thread-Sperren des Threading-Moduls zum Schreiben auf die Festplatte verwenden. Es gibt auch eine Barriere, wenn Sie jeden Frame über alle Threads hinweg synchronisieren möchten.


Beantwortet von –
Ahmed AEK


Antwort geprüft von –
David Marino (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like