2011-05-07 13 views
9

De http://docs.python.org/library/functions.html#open¿Por qué la salida estándar del subproceso (redirigido a un archivo sin búfer) se almacena en el búfer?

El argumento bufsize opcional especifica deseado tamaño de búfer del archivo: 0 significa sin búfer, 1 significa línea tamponada, cualquier otro valor positivo medios utilizan un tampón de que el tamaño (aproximadamente). Un tamaño negativo de buffete a usa el sistema predeterminado, que es , usualmente almacenado en línea para los dispositivos tty y totalmente almacenado en el búfer para otros archivos. Si se omite , se usa el sistema predeterminado.

Estoy pasando 0 como bufsize debajo sin usar flush() no hay salida escrita en el archivo cuando ejecuto main_process.
¿Cuál es el motivo?

# --------------------------------- sub_process.py 
import sys 
import time 

if __name__ == '__main__': 
    print 'printed from redirect.py' 
    # why is the following flush() needed? 'std-output' is (?) unbuffered... 
    sys.stdout.flush() 
    time.sleep(6) 


# --------------------------------- main_process.py 
import subprocess 
import time 

if __name__ == '__main__': 
    p = subprocess.Popen(
     ['python', 'sub_process.py'], 
     stdout=open('std-output', 'w', 0)) 
    time.sleep(3) 
    p.terminate() 
+0

+1, pasé unos 30 minutos tratando de descubrir por qué 'sys.stdout' ->' subprocess.PIPE' no funcionaba hace un par de días. 'flush()' es la respuesta, pero ¿por qué lo necesitamos? –

Respuesta

5

Extendiendo solución Magnus Skog (1 por cierto :)):

Bueno, básicamente lo que sucede es que cuando subproceso bifurcará un nuevo proceso duplicará el argumento stdout al nuevo subproceso stdout (fileno = 1) usando os.dup2 (mira subprocess.Popen._execute_child) y esto mantendrá el estado no búfer (como lo hace dup2), todo hasta ahora es bueno, pero cuando python se lanzará (en el subproceso) de manera predeterminada si python no ve el indicador -u configurará el búfer de stdout en el búfer de línea (eche un vistazo al main python function.) que anulará el indicador de almacenamiento en búfer que estableció anteriormente.

Espero que esto explique más el comportamiento que estaba viendo.

+0

+1 atrás :) Gracias por aclarar esto. – ralphtheninja

6

Uso de pitón con la bandera -u, por ejemplo:

if __name__ == '__main__': 
    p = subprocess.Popen(
     ['python', '-u', 'sub_process.py'], 
     stdout=open('std-output', 'w')) 
    time.sleep(3) 
    p.terminate() 
+0

Esto funciona, gracias. Sin embargo, todavía me pregunto por qué se necesita en absoluto? –

+0

Supongo que si escribe directamente en el archivo con file.write() se realizará sin búfer, pero en realidad está escribiendo indirectamente, ya que python almacenará en búfer sus comandos de impresión antes de enviar los datos a su archivo, por lo tanto, need -u flag para decirle a python que no almacene los comandos de impresión. – ralphtheninja

+0

'sys.stdout.write ('printed from redirect.py')' da el mismo resultado que print - nada se escribe en un archivo –

Cuestiones relacionadas