2009-07-22 12 views
5

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?

Antwort

1

nach Profilierung läuft ich viel Zeit im Schlaf verbracht zu sehen, und ich frage mich, wenn ich das ändern sollte, um stattdessen das Polling zu verwenden.

Sieht aus wie Sie bereits synchrone Abfrage tun, indem er den Zustand in regelmäßigen Abständen zu überprüfen. Mach dir keine Sorgen über die Zeit "verbraucht" in sleep, es wird keine CPU-Zeit essen. Es übergibt nur die Kontrolle an das Betriebssystem, das den Prozess nach einer angeforderten Zeitüberschreitung aufwacht.

Sie könnten asynchrone Ereignisschleife mit einer Bibliothek in Betracht ziehen, die Benachrichtigungen über Dateisystemänderungen abhört, die vom Betriebssystem bereitgestellt werden, aber überlegen Sie zuerst, ob es Ihnen in dieser speziellen Situation echte Vorteile bringt.

3

Warum verwenden Sie nicht einen Python-Wrapper für eine der Bibliotheken zur Überwachung von Dateiänderungen, wie gamin oder inotify (Suche nach pyinotify, ich darf nur einen Hyperlink als neuen Benutzer veröffentlichen ...) - das ist sicher schneller und die Low-Level-Zeug ist bereits auf C-Ebene für Sie getan, Kernel-Schnittstellen ...

+0

Ich benutze BSD so inotify ist nicht verwendbar und es sieht aus wie gamin ist auch nicht. – gdm

+0

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. –

6

FreeBSD und damit Mac OS X bieten ein Analog von Inotify namens kqueue. Geben Sie man 2 kqueue auf einem FreeBSD-Rechner ein, um weitere Informationen zu erhalten. Für kqueue auf Freebsd haben Sie PyKQueue verfügbar unter http://people.freebsd.org/~dwhite/PyKQueue/, wird leider nicht aktiv gepflegt, so dass Ihre Laufleistung variieren kann.

+1

Ah danke dafür. Zum Zeitpunkt des Schreibens aller SO-Fragen zum Ansehen eines Verzeichnisses geben OS X keine Antworten. – Purrell

0

Sie vielleicht einen Blick auf select.kqueue haben wollen - ich habe es nicht, aber kqueue ist die richtige Schnittstelle für den unter BSD Ich glaube, so können Sie Dateien/Verzeichnisse überwachen und zurück, wenn und nur dann aufgerufen werden, wenn sie

ändern
0

Ich habe eine Bibliothek geschrieben und ein Shell-Tool, das dies für Sie behandeln soll.

http://github.com/gorakhargosh/watchdog

Zwar ist kqueue ein sehr Schwergewicht Weise Verzeichnisse zu überwachen ich schätzen würde, wenn Sie irgendwelche Leistung testen und Prüfung können Probleme auftreten können. Patches sind ebenfalls willkommen.

HTH.