Mit select / Umfrage / kqueue / kevent ein Verzeichnis für neue Dateien zu sehen
-
19-09-2019 - |
Frage
In meiner app brauche ich ein Verzeichnis für neue Dateien zu sehen. Die Menge des Verkehrs ist sehr groß und es wird pro Sekunde erscheint ein Minimum von Hunderten von neuen Dateien sein. Derzeit verwende ich ein Besetzt Schleife mit dieser Art von Idee:
while True:
time.sleep(0.2)
if len(os.listdir('.')) > 0:
# do stuff
Nach Profilierung läuft ich sehe viel Zeit im Schlaf verbracht, und ich frage mich, ob ich diese Abfrage zu verwenden, anstatt ändern sollte.
Ich versuche, eine der verfügbaren Klassen in select
zu verwenden, um mein Verzeichnis abzufragen, aber ich bin nicht sicher, ob es tatsächlich funktioniert, oder wenn ich es falsch, nur mache.
Ich erhalte eine fd für mein Verzeichnis mit:
fd = os.open('.', os.O_DIRECT)
Ich habe dann verschiedene Methoden versucht, wenn die Verzeichnis-Änderungen zu sehen. Als Beispiel habe ich eines der Dinge ausprobierten war:
poll = select.poll()
poll.register(fd, select.POLLIN)
poll.poll() # returns (fd, 1) meaning 'ready to read'
os.read(fd, 4096) # prints largely gibberish but i can see that i'm pulling the files/folders contained in the directory at least
poll.poll() # returns (fd, 1) again
os.read(fd, 4096) # empty string - no more data
Warum ist poll () Handeln wie es mehr Informationen zu lesen ist? Ich nahm an, dass es nur tun würde, wenn etwas in dem Verzeichnis geändert hatte.
Ist das, was ich versuche, hier sogar möglich, zu tun?
Wenn nicht, gibt es eine andere bessere Alternative zu while True: look for changes
?
Lösung
Nach Profilierung läuft ich sehe viel Zeit im Schlaf verbracht, und ich frage mich, ob ich diese Abfrage zu verwenden, anstatt ändern sollte.
Sieht aus wie Sie bereits tun synchrone Abfrage, indem er den Zustand in regelmäßigen Abständen zu überprüfen. Nicht über die Zeit „verbraucht“ in sleep
Sorge, es wird keine CPU-Zeit essen. Es geht nur Steuerung an das Betriebssystem, das den Prozess nach einem angeforderten Timeout wacht.
Sie könnten asynchrone Ereignisschleife betrachten eine Bibliothek, die vom Betriebssystem zur Verfügung gestellt Meldungen ändern, um Dateisystem hört aber zunächst prüfen, ob es Ihnen echte Vorteile in dieser besonderen Situation gibt.
Andere Tipps
FreeBSD und damit Mac OS X ein Analogon von inotify genannt kqueue bieten. Typ Mann 2 kqueue auf einem FreeBSD-Rechner für weitere Informationen. Für kqueue auf Freebsd haben Sie PyKQueue verfügbar unter http://people.freebsd.org/~dwhite/ PyKQueue / wird leider nicht aktiv gehalten, um die Leistung kann variieren.
Warum nicht einen Python-Wrapper für eine der Bibliotheken für Änderungen Überwachungsdatei, wie gamin oder inotify (für pyinotify suchen, bin ich nur einen Hyperlink als neuen Benutzer ... schreiben erlaubt) -, das sicher ist, schneller zu sein und das Low-Level-Zeug auf C-Ebene ist für Sie bereits getan Kernel-Schnittstellen ...
Sie können einen Blick auf select.kqueue haben wollen - ich habe es nicht, aber kqueue ist die richtige Schnittstelle für den unter BSD glaube ich, so können Sie Dateien / Verzeichnisse überwachen und zurück, wenn und nur dann aufgerufen werden, wenn sie
ändernIch habe eine Bibliothek und ein Shell-Tool geschrieben, dass dies für Sie behandeln soll.
http://github.com/gorakhargosh/watchdog
Zwar ist kqueue ein sehr Schwergewicht Weise Verzeichnisse zu überwachen, Ich würde schätzen, wenn Sie irgendeine Leistung testen und Prüfung können Probleme auftreten könnten. Patches sind auch willkommen.
HTH.