In meiner App muss ich ein Verzeichnis für neue Dateien ansehen. Die Menge an Datenverkehr ist sehr groß und es werden mindestens Hunderte von neuen Dateien pro Sekunde erscheinen. Derzeit verwende ich ein Besetzt Schleife mit dieser Art von Idee:Mit select/poll/kqueue/kevent ein Verzeichnis für neue Dateien ansehen
while True:
time.sleep(0.2)
if len(os.listdir('.')) > 0:
# do stuff
Nach Profilierung läuft ich viel Zeit im Schlaf verbrachte bin zu sehen, und ich frage mich, ob ich sollte diese Abfrage zu verwenden, ändern stattdessen.
Ich versuche, eine der verfügbaren Klassen in select
zu verwenden, um mein Verzeichnis abzufragen, aber ich bin mir nicht sicher, ob es tatsächlich funktioniert, oder wenn ich es nur falsch 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, versucht 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 sich etwas im Verzeichnis geändert hätte.
Ist das, was ich hier versuche, sogar möglich?
Wenn nicht, gibt es noch eine andere bessere Alternative zu while True: look for changes
?
Ich benutze BSD so inotify ist nicht verwendbar und es sieht aus wie gamin ist auch nicht. – gdm
Die gamina docs sagt, dass es unter FreeBSD verwendbar ist, aber eine weniger optimale Polling-Lösung verwendet - es könnte trotzdem schneller sein als alles andere. –