Tengo un progtwig de Python que ejecuta una simulación de Monte Carlo para encontrar respuestas a preguntas de probabilidad. Estoy usando multiprocesamiento y aquí está en pseudo código
import multiprocessing def runmycode(result_queue): print "Requested..." while 1==1: iterations +=1 if "result found (for example)": result_queue.put("result!") print "Done" processs = [] result_queue = multiprocessing.Queue() for n in range(4): # start 4 processes process = multiprocessing.Process(target=runmycode, args=[result_queue]) process.start() processs.append(process) print "Waiting for result..." result = result_queue.get() # wait for process in processs: # then kill them all off process.terminate() print "Got result:", result
Me gustaría extender esto para poder mantener un recuento unificado de la cantidad de iteraciones que se han ejecutado. Al igual que si el subproceso 1 se ejecutó 100 veces y el subproceso 2 se ejecutó 100 veces, quiero mostrar un total de 200 iteraciones, como una impresión en la consola. Me refiero a la variable de iterations
en el proceso del hilo. ¿Cómo puedo asegurarme de que TODAS las hebras se agreguen a la misma variable? Pensé que usar una versión Global
de iterations
funcionaría pero no lo hace.
Las variables globales normales no se comparten entre procesos de la forma en que se comparten entre subprocesos. Necesita utilizar una estructura de datos que tenga en cuenta el proceso. Para su caso de uso, un multiprocessing.Value
debería funcionar bien:
import multiprocessing def runmycode(result_queue, iterations): print("Requested...") while 1==1: # This is an infinite loop, so I assume you want something else here with iterations.get_lock(): # Need a lock because incrementing isn't atomic iterations.value += 1 if "result found (for example)": result_queue.put("result!") print("Done") if __name__ == "__main__": processs = [] result_queue = multiprocessing.Queue() iterations = multiprocessing.Value('i', 0) for n in range(4): # start 4 processes process = multiprocessing.Process(target=runmycode, args=(result_queue, iterations)) process.start() processs.append(process) print("Waiting for result...") result = result_queue.get() # wait for process in processs: # then kill them all off process.terminate() print("Got result: {}".format(result)) print("Total iterations {}".format(iterations.value))
Algunas notas:
Value
a los niños, para mantener el código compatible con Windows, que no puede compartir las variables globales de lectura / escritura entre padres e hijos. if __name__ == "__main__":
un if __name__ == "__main__":
guard, de nuevo para ayudar con la compatibilidad de Windows, y solo como una mejor práctica general.