2012-02-19 10 views
9

Estoy intentando crear una aplicación web simple usando Python en GAE. La aplicación necesita generar algunos hilos por solicitud recibida. Para esto estoy usando la biblioteca de hilos de python. Engendro todos los hilos y luego los espero.Subprocesos GAE python que no se ejecutan en paralelo

t1.start() 
t2.start() 
t3.start() 

t1.join() 
t2.join() 
t3.join() 

La aplicación se ejecuta bien, excepto por el hecho de que los hilos se ejecutan en serie en lugar de simultáneamente (confirmó esto mediante la impresión de las marcas de tiempo al principio/final del método de cada hilo run()). He seguido las instrucciones dadas en http://code.google.com/appengine/docs/python/python27/using27.html#Multithreading para permitir multithreading

Mi app.yaml parece:

application: myapp 
version: 1 
runtime: python27 
api_version: 1 
threadsafe: true 

handlers: 
- url: /favicon\.ico 
    static_files: favicon.ico 
    upload: favicon\.ico 

- url: /stylesheet 
    static_dir: stylesheet 

- url: /javascript 
    static_dir: javascript 

- url: /pages 
    static_dir: pages 

- url: .* 
    script: main.app 

Me aseguré de que mi GoogleAppLauncher local utiliza Python 2.7 para definir la ruta de forma explícita en las preferencias.

Mis hilos tienen un tiempo de ejecución promedio de 2-3 segundos en el que hacen una llamada abierta de url y realizan algún procesamiento en el resultado.

¿Estoy haciendo algo mal o me falta algo de configuración para habilitar el subprocesamiento múltiple?

Respuesta

17

¿Lo está experimentando en el dev_appserver o después de subir su aplicación al servicio de producción? A partir de su mención de GoogleAppLauncher, parece que puede estar viendo esto en el dev_appserver; dev_appserver no emula el comportamiento de subprocesamiento de los servidores de producción, y se sorprendería al descubrir que funciona bien después de implementar su aplicación. (Si no es así, añadir un comentario aquí.)

Otra idea: si está mayormente esperando la urlfetch, puede ejecutar muchas urlfetch llamadas en paralelo mediante la interfaz asíncrona a URLFETCH: http://code.google.com/appengine/docs/python/urlfetch/asynchronousrequests.html

Este enfoque no requiere hilos. (Todavía no paraleliza correctamente las solicitudes en el dev_appserver, pero sí hace las cosas correctamente en los servidores de producción).

+0

Sí, solo estaba experimentando el problema en mi instalación local. Los hilos corrieron en paralelo cuando cargué mi aplicación. Gracias por la ayuda. – Nitesh

1

Las notas de subprocesos múltiples para GAE son meramente para la forma en que se manejan las solicitudes; no cambian fundamentalmente la forma en que funcionan los subprocesos de Python. Específicamente, se aplica la nota "Detalles de implementación de CPython" en el threading module docs.

También vale la pena mencionar la nota en la sección "La zona de pruebas" de los documentos GAE:

Tenga en cuenta que las discusiones estarán acompañados por el tiempo de ejecución cuando la solicitud termina, para que los hilos no se puede ejecutar más allá del final de la solicitud

+0

Gracias Nick por la respuesta. Entonces, ¿el soporte de subprocesos múltiples en GAE implica que el GAE puede engendrar múltiples hilos para manejar las solicitudes en paralelo, pero el código de la aplicación en sí no puede generar subprocesos de ayuda? – Nitesh

+0

@Nitesh: el front-end que le entrega las solicitudes es capaz de generar múltiples instancias de su aplicación para manejar esas solicitudes, sin embargo, los hilos que usted crea en cada instancia siguen estando sujetos a las reglas normales. Por supuesto, puede generar subprocesos auxiliares, pero no se ejecutarán al mismo tiempo a menos que bloqueen en E/S. –

+0

En los hilos de ayuda, estoy haciendo una llamada urllib.urlopen. ¿Esta llamada de E/S no está bloqueada? – Nitesh

0

Si sus subprocesos están esperando en su mayoría operaciones de almacén de datos, puede probar el módulo NDB que forma parte de 1.6.2. La semántica estará lo suficientemente cerca de lo que estás haciendo.

IIRC, el indicador multiproceso permite que una instancia de servidor sirva múltiples solicitudes en hilos separados, pero no le permitirá iniciar hilos usted mismo. Si no necesitó sincronizarlos antes de regresar, puede ponerlos en el número tasks y delegarlos en una o más colas de tareas.

+2

En realidad, el tiempo de ejecución de Py27 permite crear subprocesos. (Pero vea la nota agregada en la primera respuesta anterior: se unirán cuando finalice la solicitud). –

+0

Gracias por la corrección y por el consejo mucho mejor que el mío. – rbanffy

+0

Hay una nueva característica llamada "subprocesos de fondo", que son como subprocesos normales, excepto que los subprocesos de fondo no se unen implícitamente al final de una solicitud: https://developers.google.com/appengine/docs/python/backends/background_thread – allyourcode

Cuestiones relacionadas