2011-08-15 28 views
5

Acabo de descubrir un error extraño en mi programa relacionado con su uso del módulo de multiprocesamiento de Python. Todo funciona bien cuando ejecuto el programa desde la fuente en mi máquina. Pero lo he estado construyendo en un ejecutable usando el instalador de piro, y por alguna razón el comportamiento del multiprocesamiento cambia drásticamente cuando ejecuto el ejecutable creado a partir de mi código. Específicamente, cuando intento ejecutar la parte de multiprocesamiento de mi código, en lugar de hacer lo que se supone que debe hacer, aparece lo que parece ser una copia de la ventana principal de mi programa, una para cada proceso. Peor aún, vuelven a abrir si se cierran manualmente, presumiblemente porque son parte de un multiprocesamiento. No se imprimen mensajes de error, y una vez creadas todas las ventanas se quedan allí sin hacer nada. ¿Qué podría estar pasando para causar esto?Python - Multiprocesamiento.procesos se convierten en copias del proceso principal cuando se ejecutan desde el ejecutable

+2

Lo encontré - al parecer, el multiprocesamiento está muy por delante de mí. Para cualquiera que se lo pregunte, todo lo que necesitaba era llamar a freeze_support(). http://docs.python.org/library/multiprocessing.html#multiprocessing.freeze_support Aunque se supone que debe generar un RuntimeError inmediatamente, entonces no estoy seguro de por qué se ejecutó ... – dpitch40

Respuesta

8

En Windows multiprocessing, trata de emular la llamada al sistema Unix fork() iniciando nuevas instancias de su ejecutable, y ejecutar la rutina de proceso hijo (multiprocessing.forking.main()) en su interior. Con el intérprete estándar de Python (python.exe), multiprocessing puede pasar el parámetro -c para ejecutar código personalizado. Para ejecutables personalizados, sin embargo, esto no es posible, ya que probablemente el ejecutable no admita las mismas opciones de línea de comando que python.exe.

La función freeze_support() evita este problema ejecutando explícitamente la rutina de proceso secundario y termina el intérprete llamando al sys.exit(). Si olvida llamar al freeze_support(), el nuevo proceso no sabe que es un proceso secundario y ejecuta la lógica de la aplicación principal. En su caso, esto abrirá otra ventana principal de la GUI.

Desde el inicio de un nuevo proceso hijo del proceso recién creado hará que la recursividad infinita, multiprocessing intenta evitar que esto comprobando el atributo sys.frozen y formar una RuntimeError si freeze_support() no fue llamado. En su caso, parece que se requiere la interacción del usuario para engendrar los procesos, por lo tanto, no hay recursión infinita ni RuntimeError.

Por convenio, sys.frozen solo está configurado para los ejecutables generados automáticamente creados por py2exe o PyInstaller. Es importante comprender esta lógica y establecer sys.frozen en True cuando desee incrustar Python en un archivo ejecutable personalizado que permita el multiprocesamiento en Windows.

Cuestiones relacionadas