Select/Poll/Kqueue/Kevent를 사용하여 새 파일의 디렉토리를 시청
-
19-09-2019 - |
문제
내 앱에서는 새 파일에 대한 디렉토리를 시청해야합니다. 트래픽의 양은 매우 크며 초당 최소 수백 개의 새 파일이 나타날 것입니다. 현재 저는 이런 종류의 아이디어로 바쁜 루프를 사용하고 있습니다.
while True:
time.sleep(0.2)
if len(os.listdir('.')) > 0:
# do stuff
프로파일 링을 마친 후 나는 수면에서 많은 시간을 보냈고, 대신 폴링을 사용하기 위해 이것을 바꿔야하는지 궁금합니다.
사용 가능한 클래스 중 하나를 사용하려고합니다. select
내 디렉토리를 폴링하기 위해서는 실제로 작동하는지 아니면 그냥 잘못하고 있는지 확실하지 않습니다.
내 디렉토리에 대한 FD를 다음과 같이받습니다.
fd = os.open('.', os.O_DIRECT)
그런 다음 디렉토리가 언제 변경되는지 확인하기 위해 몇 가지 방법을 시도했습니다. 예를 들어, 내가 시도한 것 중 하나는 다음과 같습니다.
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
Poll ()가 더 많은 정보를 읽을 수있는 것처럼 행동하는 이유는 무엇입니까? 디렉토리에서 무언가가 변경된 경우에만 그렇게 할 것이라고 가정했습니다.
내가 여기서 할 수있는 일이 가능합니까?
그렇지 않다면, 다른 더 나은 대안이 있습니까? while True: look for changes
?
해결책
프로파일 링을 마친 후 나는 수면에서 많은 시간을 보냈고, 대신 폴링을 사용하기 위해 이것을 바꿔야하는지 궁금합니다.
이미 당신처럼 보입니다 하다 정기적으로 상태를 확인하여 동기 폴링. "소비 된"시간에 대해 걱정하지 마십시오 sleep
, CPU 시간을 먹지 않습니다. 요청 된 시간 초과 후 프로세스를 깨우는 운영 체제에 제어를 전달합니다.
운영 체제가 제공하는 파일 시스템 변경 알림을 듣는 라이브러리를 사용하여 비동기 이벤트 루프를 고려할 수 있지만,이 특정 상황에서 실질적인 혜택을 제공하는 경우 먼저 고려하십시오.
다른 팁
freebsd와 mac os x는 kqueue라는 Inotify의 아날로그를 제공합니다. 자세한 내용은 FreeBSD 머신에 Man 2 Kqueue를 입력하십시오. freebsd의 Kqueue의 경우 Pykqueue를 사용할 수 있습니다 http://people.freebsd.org/~dwhite/pykqueue/, 불행히도 적극적으로 유지되지 않으므로 마일리지가 다를 수 있습니다.
파일 변경 모니터링을 위해 라이브러리 중 하나에 파이썬 래퍼를 사용하지 않는 이유는 무엇입니까? 집 없는 아이 또는 inotify (pyinotify 검색, 하나의 하이퍼 링크를 새로운 사용자로만 게시 할 수 있습니다 ...) - 더 빠르며 저수준 작업은 커널 인터페이스를 사용하여 C 레벨에서 이미 수행되었습니다. .
당신은보고 싶을 수도 있습니다 select.kqueue - 나는 그것을 사용하지 않았지만 Kqueue는 BSD에 따라 이것에 대한 올바른 인터페이스입니다. 나는 당신이 파일 / 디렉토리를 모니터링하고 변경할 때만 다시 호출 될 수 있다고 생각합니다.
나는 당신을 위해 이것을 처리 해야하는 도서관과 쉘 도구를 작성했습니다.
http://github.com/gorakhargosh/watchdog
그러나 Kqueue는 디렉토리를 모니터링하는 매우 헤비급 방법이지만 발생할 수있는 성능 문제를 테스트하고 체크 아웃 할 수 있다면 감사하겠습니다. 패치도 환영합니다.
HTH.