El uso de selección / encuesta / kqueue / kevent para ver un directorio para los archivos nuevos

StackOverflow https://stackoverflow.com/questions/1165571

Pregunta

En mi aplicación tengo que ver un directorio para los archivos nuevos. La cantidad de tráfico es muy grande y no va a haber un mínimo de cientos de nuevos archivos por segundo que aparece. Actualmente estoy usando un bucle ocupado con este tipo de idea:

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

Después de ejecutar perfiles que estoy viendo una gran cantidad de tiempo pasado en el sueño, y me pregunto si debería cambiar esta opción para utilizar el sondeo en su lugar.

Estoy tratando de utilizar una de las otras clases en select para sondear mi directorio, pero no estoy seguro de si realmente funciona, o si sólo estoy haciendo mal.

Me aparece un fd para mi directorio con:

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

He intentado varios métodos a continuación para ver cuando los cambios en el directorio. A modo de ejemplo, una de las cosas que intenté fue:

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

¿Por qué es poll (), que actúa como que hay más información para leer? Supuse que sólo haría que si algo había cambiado en el directorio.

Es lo que estoy tratando de hacer aquí es posible?

Si no es así, ¿hay alguna otra alternativa mejor a while True: look for changes?

¿Fue útil?

Solución

  

Después de ejecutar perfiles que estoy viendo una gran cantidad de tiempo pasado en el sueño, y me pregunto si debería cambiar esta opción para utilizar el sondeo en su lugar.

Parece que ya lo de votación sincrónica, comprobando el estado a intervalos regulares. No se preocupe por el tiempo "invertido" en sleep, no va a comer el tiempo de CPU. Simplemente pasa el control al sistema operativo que despierta el proceso después de un tiempo de espera requerido.

Se podría considerar bucle de eventos asíncronos utilizando una biblioteca que escucha del sistema de ficheros notificaciones de cambio proporcionadas por el sistema operativo, pero considerar en primer lugar si se le da ningún beneficio real en esta situación particular.

Otros consejos

FreeBSD y Mac OS X por lo tanto proporcionan un análogo de inotify llamada kqueue. Teclee man 2 kqueue en una máquina FreeBSD para más información. Para kqueue en FreeBSD tiene PyKQueue disponibles en http://people.freebsd.org/~dwhite/ PyKQueue / , por desgracia no se mantiene activa por lo que su experiencia puede variar.

¿Por qué no utilizar un envoltorio de Python para una de las bibliotecas de cambios en los archivos de vigilancia, como gamin o inotify (buscar pyinotify, yo sólo estoy autorizado para publicar un hipervínculo como un nuevo usuario ...) - que es seguro que será más rápido y el material de bajo nivel ya está hecho a nivel C para usted , utilizando interfaces del núcleo ...

Es posible que desee echar un vistazo a select.kqueue - yo no lo he utilizado pero kqueue es la interfaz correcta para esto bajo BSD creo para que pueda supervisar los archivos / directorios y ser llamado de nuevo cuando, y sólo cuando cambian

He escrito una biblioteca y una herramienta de shell que debe manejar esto para usted.

http://github.com/gorakhargosh/watchdog

A pesar de que, kqueue es una manera muy pesado para controlar los directorios Te agradecería si puede probar y reservar en cualquier actuación problemas que pueden surgir. Los parches también son bienvenidos.

HTH.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top