Lettura Python da stdin mentre si eseguono altre attività

1

Sto cercando di scrivere un parser di log di sistema. Riceverà messaggi dal demone syslog di FreeBsd tramite stdin.

Utilizzerà quei messaggi per determinare se un IP dovrebbe essere bannato o meno. Il problema che ho è che dopo x secondi il blocco dovrebbe essere rimosso, ma se non avrò alcun input da stdin, il mio programma bloccherà solo ad attenderlo. Quindi nel frattempo non posso fare nulla.

L'ho risolto usando i thread, ma non c'è un modo migliore per farlo?

Ad esempio qualcosa del genere:

while true:
    while <data in stdin>:
        handleData

    doSomeStuff()

Quindi finché non arriva nulla da stdin voglio eseguire doSomeStuff e se ci sono dei dati gestirlo.

    
posta user2246190 09.05.2013 - 21:45
fonte

2 risposte

2

Questo è un esempio perfetto per usare il multithreading.

Crea un thread "worker" e un altro thread, che attende l'input dell'utente. Quando il thread "input" riceve input, può aggiungere un elemento a un elenco "todo" (con una sorta di blocco per escludere le condizioni di gara).

Quindi, il thread worker può recuperare l'elemento più in alto ed eseguirlo. Nel tuo caso dovrebbe anche aggiungere un altro elemento per "unbanning" l'IP in seguito, il che significa che ogni attività dovrebbe avere un tag "time" di qualche tipo.

Una struttura ragionevole per implementare questo è un albero rosso-nero o un heap binario con l'ordinamento in base al valore "ora".

Quindi, il tuo thread di lavoro controlla se è giunto il momento di eseguire l'oggetto top nella lista 'todo', lo esegue e dorme un po 'di tempo ragionevole (diciamo 100 ms).

D'altro canto, il thread di input attende input e, quando viene presentato con esso, aggiunge un'attività con l'ora corrente (che garantisce che venga quasi immediatamente rilevata dal thread worker).

    
risposta data 09.05.2013 - 22:18
fonte
3

I thread stanno bene, e non c'è davvero niente di sbagliato nell'usarli qui. Per completezza, c'è anche select() , che ti consente di eseguire un controllo di blocco per l'input in sospeso su un descrittore di file, con un timeout. Se si utilizza questa funzione in un ciclo, intervallata dall'attività temporizzata, si otterrà più o meno lo stesso comportamento simultaneo, ma implementato su un singolo thread. Questo è il binding Python per select() e i suoi amici, btw.

    
risposta data 10.05.2013 - 00:19
fonte

Leggi altre domande sui tag