2009-07-22 10 views
5

W mojej aplikacji muszę oglądać katalog dla nowych plików. Ilość ruchu jest bardzo duża i pojawią się minimum setki nowych plików na sekundę. Obecnie używam ruchliwą pętlę z tego rodzaju idea:Używanie select/poll/kqueue/kevent do oglądania katalogu dla nowych plików

while True: 
    time.sleep(0.2) 
    if len(os.listdir('.')) > 0: 
    # do stuff 

Po uruchomieniu profilowanie widzę dużo czasu spędzonego w sen, a ja zastanawiałem się, czy powinienem to zmienić w użyciu sondowania zamiast.

Próbuję użyć jednej z dostępnych klas w select do odpytywania mojego katalogu, ale nie jestem pewien, czy to faktycznie działa, czy też robię to źle.

dostaję fd do mojego katalogu z:

fd = os.open('.', os.O_DIRECT) 

ja potem próbowaliśmy kilka metod, aby zobaczyć, kiedy zmiany katalogów. Jako przykład, jedną z rzeczy, którą próbowałem było:

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 

Dlaczego poll() działa tak, jak jest więcej informacji do przeczytania? Zakładałem, że zrobi to tylko, jeśli coś zmieni się w katalogu.

Czy to, co próbuję tutaj zrobić, jest możliwe?

Jeśli nie, czy istnieje jakaś lepsza alternatywa dla while True: look for changes?

Odpowiedz

1

Po uruchomieniu profilowania widzę dużo czasu spędzonego we śnie i zastanawiam się jeśli powinienem to zmienić, aby zamiast tego użyć odpytywania.

Wygląda na to, że już zrobić synchronicznego odpytywanie, sprawdzając stan w regularnych odstępach czasu. Nie martw się o czas "spędzony" w sleep, nie będzie on jadł czasu procesora. Po prostu przekazuje kontrolę systemowi operacyjnemu, który budzi proces po żądanym czasie oczekiwania.

Można rozważyć asynchroniczną pętlę zdarzeń za pomocą biblioteki, która nasłuchuje powiadomień o zmianach systemu plików dostarczanych przez system operacyjny, ale należy najpierw rozważyć, czy przynosi ona rzeczywiste korzyści w tej konkretnej sytuacji.

3

Dlaczego nie używać opakowania Pythona dla jednej z bibliotek do monitorowania zmian w plikach, takich jak gamin lub inotify (szukaj pyinotify, mogę wysyłać tylko jeden hiperlink jako nowy użytkownik ...) - to na pewno być szybszym, a rzeczy niskiego poziomu są już na poziomie C dla ciebie, używając interfejsów jądra ...

+0

Używam BSD, więc inotify nie nadaje się do użytku i wygląda na to, że gamin też nie jest. – gdm

+0

Gamin docs mówi, że można go używać w FreeBSD, ale korzysta z mniej optymalnego rozwiązania ankietowego - może być jeszcze szybszy niż cokolwiek innego, dzięki za to. –

6

FreeBSD i tym samym system Mac OS X udostępnia analogię inotify o nazwie kqueue. Wpisz man 2 kqueue na maszynie FreeBSD, aby uzyskać więcej informacji. Dla Kqueue na Freebsd masz PyKQueue dostępne pod http://people.freebsd.org/~dwhite/PyKQueue/, niestety nie jest aktywnie utrzymywany, więc twój przebieg może się różnić.

+1

Ah. W chwili pisania wszystkich pytań SO dotyczących oglądania katalogu nie dają odpowiedzi OS X. – Purrell

0

Czasami warto spojrzeć na select.kqueue - Nie używałem go, ale KQUEUE jest odpowiedni interfejs do tego pod BSD Wierzę więc można monitorować pliki/katalogi i nazwać powrotem wtedy i tylko wtedy, gdy zmieni

0

Napisałem bibliotekę i narzędzie powłoki, które powinno obsługiwać to za Ciebie.

http://github.com/gorakhargosh/watchdog

Chociaż KQUEUE jest bardzo wysokiej gramaturze sposób monitorowania katalogów będę wdzięczny, jeśli można przetestować i kasy żadnych problemów z wydajnością można napotkać. Patche są również mile widziane.

HTH.

Powiązane problemy