Domanda

Nella mia app ho bisogno di guardare una directory per i nuovi file. La quantità di traffico è molto grande e ci stanno per essere un minimo di centinaia di nuovi file al secondo apparire. Attualmente sto usando un ciclo occupato con questo tipo di idea:

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

Dopo l'esecuzione di profilazione che sto vedendo un sacco di tempo trascorso nel sonno, e mi chiedo se dovrei cambiare questa opzione per utilizzare il polling invece.

Sto cercando di utilizzare una delle classi disponibili in select per interrogare il mio elenco, ma non sono sicuro se funziona davvero, o se sto solo facendo male.

ho un fd per la mia directory con:

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

Ho poi provato diversi metodi per vedere quando le modifiche alla directory. A titolo di esempio, una delle cose che ho provato è stato:

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

Perché è poll () che agisce come se non ci sono più informazioni da leggere? Ho pensato che sarebbe fare solo che se qualcosa fosse cambiato nella directory.

è quello che sto cercando di fare qui anche possibile?

In caso contrario, c'è qualche altra alternativa migliore per while True: look for changes?

È stato utile?

Soluzione

  

Dopo l'esecuzione di profilazione che sto vedendo un sacco di tempo trascorso nel sonno, e mi chiedo se dovrei cambiare questa opzione per utilizzare il polling invece.

Sembra che tu già do polling sincrono, controllando lo stato ad intervalli regolari. Non preoccuparti per il tempo "speso" in sleep, non mangerà tempo di CPU. Passa solo il controllo al sistema operativo, che si sveglia il processo dopo un timeout richiesto.

Si potrebbe prendere in considerazione ciclo di eventi asincroni utilizzando una libreria che ascolta filesystem notifiche di modifica previste dal sistema operativo, ma esaminare in primo luogo se ti dà alcun beneficio reale in questa particolare situazione.

Altri suggerimenti

FreeBSD e quindi Mac OS X forniscono un analogo di inotify chiamato kqueue. Digitare man 2 kqueue su una macchina FreeBSD per ulteriori informazioni. Per kqueue su FreeBSD avete PyKQueue disponibili alla pagina http://people.freebsd.org/~dwhite/ PyKQueue / , purtroppo non è mantenuta attiva così il vostro chilometraggio può variare.

Perché non utilizzare un wrapper Python per una delle librerie per modifiche apportate ai file di monitoraggio, come gamin o inotify (ricerca di pyinotify, mi è permesso solo per pubblicare un collegamento ipertestuale come nuovo utente ...) - che è sicuro di essere più veloce e la roba di basso livello è già stato fatto a livello C per voi , utilizzando le interfacce del kernel ...

Si potrebbe desiderare di avere uno sguardo a select.kqueue - non ho usato, ma kqueue è l'interfaccia giusta per questo sotto BSD credo in modo da poter monitorare file / directory ed essere richiamato quando e solo quando cambiano

Ho scritto una biblioteca e uno strumento di shell che dovrebbe gestire questo per voi.

http://github.com/gorakhargosh/watchdog

Anche se, kqueue è un modo molto pesante per monitorare le directory Ti sarei grato se è possibile testare e checkout qualsiasi prestazione problemi che potrebbero verificarsi. Le patch sono i benvenuti.

HTH.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top