starmap set_start_method parallelize how from python logging concurrency multiprocessing

python - set_start_method - Salida de registro de multiprocesamiento.Proceso



python pool process (3)

¿Hay alguna forma de registrar el resultado de stdout de un proceso determinado al usar la clase multiprocesamiento.Proceso en python?


Puede configurar sys.stdout = Logger() donde Logger es una clase cuyo método de write (inmediatamente, o acumulando hasta que se detecta /n ) llama a logging.info (o de cualquier otra forma que desee iniciar sesión). Un ejemplo de esto en acción.

No estoy seguro de lo que quiere decir con un proceso "dado" (¿quién lo ha otorgado, qué lo distingue de todos los demás ...?), Pero si quiere decir que sabe qué proceso desea destacar de esa manera en el momento en que crear una instancia, luego puede ajustar su función de target (y solo) - o el método de run que está anulando en una subclase de Process - en un contenedor que realiza esta "redirección" sys.stdout - y dejar otros procesos solo .

Tal vez si afinan un poco las especificaciones, puedo ayudar con más detalle ...


Solo hay dos cosas que agregaría a la respuesta de @Mark Rushakoff. Al depurar, me pareció realmente útil cambiar el parámetro de buffering de mis llamadas open() a 0.

sys.stdout = open(str(os.getpid()) + ".out", "a", buffering=0)

De lo contrario, locura , porque al rastrear el archivo de salida, los resultados pueden ser muy intermitentes. buffering=0 para tail -f great.

Y para completar, hazte un favor y redirecciona sys.stderr también.

sys.stderr = open(str(os.getpid()) + "_error.out", "a", buffering=0)

Además, por comodidad, puede volcarlo en una clase de proceso separada si lo desea,

class MyProc(Process): def run(self): # Define the logging in run(), MyProc''s entry function when it is .start()-ed # p = MyProc() # p.start() self.initialize_logging() print ''Now output is captured.'' # Now do stuff... def initialize_logging(self): sys.stdout = open(str(os.getpid()) + ".out", "a", buffering=0) sys.stderr = open(str(os.getpid()) + "_error.out", "a", buffering=0) print ''stdout initialized''

Aquí está una esencia correspondiente


La manera más fácil podría ser simplemente anular sys.stdout . Modificando ligeramente un ejemplo del manual de multiprocesamiento :

from multiprocessing import Process import os import sys def info(title): print title print ''module name:'', __name__ print ''parent process:'', os.getppid() print ''process id:'', os.getpid() def f(name): sys.stdout = open(str(os.getpid()) + ".out", "w") info(''function f'') print ''hello'', name if __name__ == ''__main__'': p = Process(target=f, args=(''bob'',)) p.start() q = Process(target=f, args=(''fred'',)) q.start() p.join() q.join()

Y ejecutarlo:

$ ls m.py $ python m.py $ ls 27493.out 27494.out m.py $ cat 27493.out function f module name: __main__ parent process: 27492 process id: 27493 hello bob $ cat 27494.out function f module name: __main__ parent process: 27492 process id: 27494 hello fred