2010-03-04 5 views
9

documentazione Python per Popen stati:Qualcuno può spiegare deadlock del buffer del tubo?

Attenzione Usare comunicare() anziché .stdin.write, .stdout.read o .stderr.read evitare deadlock dovuti ad uno qualsiasi degli altri buffer OS tubazione di riempimento e bloccare il processo figlio.

Ora, sto cercando di capire come può verificarsi questo stallo e perché.

Il mio modello mentale: subproccess produce qualcosa a stdout/err, che viene memorizzato nel buffer e dopo che il buffer è stato riempito, viene svuotato allo stdout/err di subproccess, che viene inviato tramite pipe al processo padre.

Da quanto riportato nella documentazione, pipe ha il proprio buffer e al termine del riempimento o del sottoprocesso viene scaricato per il processo padre.

In entrambi i casi (con buffer di tubi o non), non sono completamente sicuro di come si possa verificare un deadlock. L'unica cosa che mi viene in mente è una sorta di processo "globale" per il buffer del pipe del sistema operativo, che suona strano. Un altro è che più processi condivideranno la stessa pipa, cosa che non dovrebbe avvenire da sola.

Qualcuno può spiegarlo?

risposta

6

Attenzione, questo ha un piccolo errore.

Il mio modello mentale: subproccess produce qualcosa da stdout/err, che è tamponato e dopo buffer viene riempito, è lavata a stdout/err di subproccess, che è inviare tramite tubo processo genitore.

Il buffer è condiviso dal processo padre e figlio.

Il sottoprocesso produce qualcosa su stdout, che è lo stesso buffer dal quale il processo padre deve leggere.

Quando il buffer è pieno, la scrittura si interrompe finché il buffer non viene svuotato. Flush non significa nulla per una pipe, poiché due processi condividono lo stesso buffer.

Flussare su disco significa che il driver di periferica deve spingere i byte verso il basso sul dispositivo. Flussare un socket significa dire al TCP/IP di smettere di aspettare per accumulare un buffer e inviare cose. Flussare su una console significa smettere di aspettare una nuova riga e spingere i byte attraverso il driver del dispositivo sul dispositivo.

+0

Questo è quello di cui non ero così sicuro. Grazie. – Almad

1

Un deadlock può verificarsi quando entrambi i buffer (stdin e stdout) sono pieni: il programma è in attesa di scrivere più input per il programma esterno e il programma esterno attende di leggere prima dal buffer di output.

Questo può essere risolto utilizzando l'I/O non bloccante e assegnando le priorità ai buffer in modo appropriato. Puoi provare a farlo funzionare da solo, ma lo communicate() lo fa solo per te.

+0

Sì, ma stiamo parlando di lettura da dati di dimensioni più grandi della memoria. Ma grazie per i chiarimenti. – Almad