2011-01-24 11 views
6

Il problema

Mi aspettavo che lo script di seguito stampasse al massimo un evento e poi si fermasse (è scritto solo per illustrare il problema).Come funziona il polling di un file per le modifiche?

#!/usr/bin/env python 

from select import poll, POLLIN 

filename = "test.tmp" 

# make sure file exists 
open(filename, "a").close() 

file = open(filename, "r+") 

p = poll() 
p.register(file.fileno(), POLLIN) 

while True: 
    events = p.poll(100) 
    for e in events: 
     print e 
     # Read data, so that the event goes away? 
     file.read() 

Tuttavia, stampa circa 70000 eventi al secondo. Perché?

Sfondo

ho scritto una classe che utilizza la classe pyudev.Monitor internamente. Tra le altre cose, esegue il polling del fileno fornito dal metodo fileno() per le modifiche utilizzando uno poll object.

Ora sto provando a scrivere un test unitario per la mia classe (mi rendo conto che dovrei prima scrivere il test unitario, quindi non c'è bisogno di indicarlo), e quindi ho bisogno di scrivere il mio fileno () metodo per il mio oggetto fittizio pyudev.Monitor, e ho bisogno di controllarlo in modo che possa attivare l'oggetto sondaggio per segnalare un evento. Come dimostra il codice precedente, non posso smettere di riportare eventi apparentemente inesistenti!

Non riesco a trovare nessun acknowledge_event() o simile nella classe di sondaggio per far sparire l'evento (sospetto che ci sia un solo evento che è in qualche modo bloccato), cercando su google e questo sito non ha dato nulla. Sto usando Python 2.6.6 su Ubuntu 10.10.

risposta

3

Avrai più fortuna nell'usare pipe piuttosto che file. Prova questo:

#!/usr/bin/env python 
import os 
from select import poll, POLLIN 

r_fd, w_fd = os.pipe() 

p = poll() 
p.register(r_fd, POLLIN) 

os.write(w_fd, 'X') # Put something in the pipe so p.poll() will return 

while True: 
    events = p.poll(100) 
    for e in events: 
     print e 
     os.read(r_fd, 1) 

Questo stamperà il singolo evento che stai cercando. Per attivare l'evento di polling, tutto ciò che devi fare è scrivere un byte nel descrittore di file scrivibile.