ylab color categoryorder python user-interface multiprocessing user-experience

color - Python: Separación del proceso de GUI del proceso de lógica central



plotly layout (5)

Estoy desarrollando un proyecto de Python para manejar simulaciones de computadora, y también estoy desarrollando una GUI para ello. (La lógica del núcleo en sí no requiere una GUI.) El kit de herramientas de GUI que uso es wxPython, pero creo que mi pregunta es lo suficientemente general como para no depender de ello.

La forma en que la GUI actualmente funciona es que inicia el paquete de lógica central (llamado garlicsim ) en el mismo proceso y el mismo hilo que la GUI. Esto funciona, pero entiendo que es un enfoque problemático, porque si la lógica central necesita hacer algunos cálculos difíciles, la GUI se bloqueará, lo cual considero inaceptable.

¿Que debería hacer?

Escuché sobre la opción de iniciar la lógica central en un proceso separado de la GUI. Esto suena interesante, pero tengo muchas preguntas sobre esto.

  1. ¿Utilizo el paquete de multiprocessing o el paquete de subprocess para iniciar el nuevo proceso?
  2. ¿Cómo puedo acceder fácilmente a los datos de simulación del proceso de GUI? Después de todo, se almacenará en el otro proceso. El usuario debería poder navegar fácilmente por la línea de tiempo de la simulación. ¿Cómo puede hacerse esto?

Desafortunadamente, aunque tiene razón en que la elección de GUI no afecta la respuesta, el mejor enfoque para este problema dependerá en gran medida de lo que hagan exactamente sus datos de simulación.

Por ejemplo, si genera datos secuenciales, entonces puede alimentarlo a su GUI a través de una cola segura o segura para procesos. Pero si muta los datos completos y su GUI necesita poder ver una instantánea en un momento dado, podría ser demasiado costoso resolverlo enviando todo el estado a lo largo de la cola y podría requerir un enfoque tipo mutex para compartir el acceso a la estructura de datos. Entonces, la naturaleza del trabajo realizado en sus datos es primordial aquí.

En cuanto a si usar multiprocesamiento o subproceso, eso depende de si tiene un programa completamente separado o si no maneja los datos. El primero es para hacer multiprocesamiento en el estilo de multihilo: son diferentes partes del mismo programa que se ejecutan en múltiples procesos. El último es cuando un programa quiere ejecutar otro (que podría ser una copia del programa, pero generalmente no lo es). De nuevo, es difícil saber cuál es el mejor enfoque para su situación específica, aunque parece que podría tener la lógica del núcleo como una aplicación de línea de comando y comunicarse a través de tuberías, enchufes, etc.


El enfoque más simple que puede funcionar para usted aquí es iniciar el cálculo en un subproceso separado y comunicar datos entre este subproceso y la GUI utilizando objetos Queue . Estos son completamente seguros y muy convenientes para la comunicación entre hilos.

Otras soluciones son más complejas: puede terminar ejecutando la simulación en un proceso de "servidor" completamente separado y comunicarse con los sockets con la GUI principal.


Para responder las preguntas específicas.

"¿Utilizo el paquete de multiprocessing o el paquete de subprocess para iniciar el nuevo proceso?"

Usa multiprocessing

"¿Cómo puedo acceder fácilmente a los datos de simulación del proceso de GUI?"

No tiene acceso a los objetos de procesos de simulación, si eso es lo que está preguntando. La simulación es un proceso separado. Puede iniciarlo, detenerlo y, lo más importante, realizar solicitudes a través de una cola de comandos que van al simulador.

"El usuario debería poder navegar a través de la línea de tiempo de la simulación de manera fácil y sin problemas. ¿Cómo se puede hacer esto?"

Esto es solo diseño. Proceso único, procesos múltiples, hilos múltiples no tienen ningún impacto en absoluto sobre esta cuestión.

Cada simulación debe tener algunos parámetros, debe comenzar, debe producir un registro (o línea de tiempo). Eso tiene que hacerse sin importar qué biblioteca use para iniciar y detener la simulación.

El resultado de la simulación, que se ingresa a su GUI, se puede hacer de un millón de maneras.

  • Base de datos. La línea de tiempo de simulación podría insertarse en una base de datos SQLite y ser consultada por la GUI. Esto no funciona muy bien porque SQLite no tiene un bloqueo realmente inteligente. Pero funciona

  • Archivo. La línea de tiempo de simulación se escribe en un archivo. La GUI lee el archivo. Esto funciona realmente, realmente bien.

  • Solicitud / respuesta. La simulación tiene múltiples hilos, uno de los cuales es quitar los comandos y responder, por ejemplo, devolviendo la línea de tiempo hasta el momento, o detener la simulación o cambiar los parámetros y reiniciarlo.


Puede encontrar algo de inspiración aquí: http://wiki.wxpython.org/LongRunningTasks , sin embargo, es para multihilo, no para multiprocesamiento.

La idea básica

  • para multihilo: use una cola de eventos para comunicarse entre la GUI y el hilo de procesamiento.
  • para multiprocesamiento: tal vez use el paquete de subproceso y use stdin / stdout del proceso hijo para comunicarse con él. Para esto, necesitas una API de línea de comandos, pero al final te resultará útil, ya que puedes realizar pruebas unitarias independientes de la GUI.

Incluso puede conducir la comunicación de E / S a través de un zócalo, esto permitiría una fácil administración de la red de la simulación.

Editar: acabo de ver el paquete de multiprocesamiento 2.6 nuevo que mencionaste. Parece una buena elección, podría usar colas para comunicarse entre procesos. Este es un acoplamiento más ajustado, puede elegir según sus necesidades.


Mutiprocesamiento o Pyro con objetos de datos distribuidos.

http://pyro.sourceforge.net/

Su simulación suministra objetos distribuidos a la GUI, la GUI los manipula y lee sus atributos.

Ambas bibliotecas proporcionarán capacidad de expansión a través de una red sin complicaciones, pero pueden ejecutarse localmente. Cuando su simulación comience a procesar demasiados números, agregue más servidores de simulación que proporcionen más objetos distribuidos.