2011-11-21 13 views
8

Estoy almacenando un diccionario en una sesión de Django a la que pueden acceder varios hilos. Todos los hilos pueden actualizar ese diccionario, los hilos también obtienen valores del diccionario para ejecutar el proceso. Quiero saber si la sesión de Django es segura o tengo que usar bloqueos o semáforos.¿Es seguro un hilo de sesión de Django?

ejemplo típico:

Thread1: 
threadDict = request.session.get('threadDict', None) 
if threadDict['stop']: 
    #break the for loop exit the thread 
else: 
    #do some processing and update some values in thread dictionary 
    threadDict['abc'] = 0 
    request.session['threadDict'] = threadDict (Point1) 

def someFunction(): 
    #this function is used to send stop signal to thread 
    threadDict = request.session.get('threadDict', None) 
    threadDict['stop'] = True 
    request.session['threadDict'] = threadDict (Point2) 

Hace existe la posibilidad de que cuando diccionario hilo Point2 actualización en sesión justo después de que actualiza Point1 también actualizarlo, entonces mi stop para dejar de hilo se pierde.

Más información

una petición Ajax inicia cuatro hilos que muestras de su descarga desde los 4 URLs diferentes. ¿Por qué usé hilos? porque quiero mostrar al usuario qué muestras se están descargando actualmente y cuáles quedan. Todos los hilos actualizarán su estado en el diccionario dentro de la sesión. Después de que se iniciaron los hilos, hago una solicitud ajax después de cada dos segundos y tomo el diccionario de la sesión y leo el estado actual de los hilos. Pero esta idea falló porque los hilos son independientes de la solicitud y su sesión. Cada solicitud de AJAX definitivamente tiene su sesión, pero no puedo pasar esa sesión a hilos porque cuando una vez comienzan son independientes del resto del mundo (puede ser que pueda pasarlo pero no puedo pasarlo tan rápido que el proceso está siendo realizado por el trapos). para abordar este problema, elijo el marco de caché en lugar de la sesión. como la memoria caché es accesible desde cualquier lugar. Los threads almacenan su estado en el diccionario y lo vuelven a poner en caché y cada dos segundos tomo el diccionario del caché y leo el estado. Y una cosa más de acuerdo con mi caché de experiencia no es seguro para subprocesos. Entonces, para cuatro hilos, utilicé cuatro diccionarios por separado.

Respuesta

6

El objeto request.session devuelto será uno nuevo para cada solicitud, accediendo al mismo almacenamiento. Además, se cargan desde el almacenamiento en el momento de la solicitud y se guardan en el momento de la respuesta. Por lo tanto, si desea transferir información de un hilo de larga ejecución a otra solicitud, debe guardarla manualmente en el hilo de larga ejecución. Lamentablemente, esto provocará la pérdida de las modificaciones de los datos de la misma sesión.

La sesión es segura para subprocesos en cierto sentido. No romperás el intérprete de esta manera. Su solicitud verá los datos de la sesión como una instantánea en el primer acceso, y al guardarlos sobrescribirá todos los cambios que hayan ocurrido desde ese momento. Entonces, el estado de la sesión será consistente, pero algunas modificaciones de las solicitudes pueden perderse.

Actualmente esta propiedad es común para prácticamente cualquier marco: cualquier sesión/caché/algún otro almacenamiento que pueda compartirse entre procesos múltiples es poco probable que proporcione modificaciones de los objetos almacenados sin posibilidad de que se sobrescriban los cambios.

+0

Si no recuerdo mal, puede editar su pregunta y agregarle la información. – Tanriol

+0

ok gracias agregué más detalles en la pregunta. –

0

Los tipos básicos en Python generalmente son seguros para hilos gracias al global interpreter lock. Este bloqueo se libera en algunas situaciones (por ejemplo, al hacer E/S) para permitir el acceso a otros subprocesos. Esto significa que usted (la aplicación) deberá mantener un estado constante en todas las llamadas que podrían liberar el GIL. Ejemplo de tales métodos son bloquear las operaciones de socket.

+0

¿Hay alguna manera de acceder a la sesión django en alguna función sin usar 'request.session' Quiero acceder directamente a la sesión? –

+0

¿Por qué no quieres usar request.session? – Krumelur

+0

Quiero almacenar el estado de los hilos en algún lugar, como hilos iniciados una vez que no puedo pasar la solicitud una y otra vez, una vez que inicio el proceso hago una solicitud ajax para verificar el estado que toma el diccionario almacenado en la sesión para saber cuál es el estado actual de los hilos. entonces, ¿estaba pensando si hay algún método para acceder directamente a la sesión para que los hilos puedan almacenar su estado? –

0

No estoy seguro de que django sea seguro para subprocesos. Por ejemplo, django/core/urlresolvers.py no es seguro para subprocesos si utiliza la configuración de Apache + mod_wsgi con varios subprocesos por proceso. pero trabajan para hacerlo. algún boleto está en el sistema de tickets de django 15849

2

La sesión Django es un diccionario recuperado al inicio del proceso de solicitud y guardado al final [source]. Por lo tanto, si realiza cambios paralelos en él, prevalecerá uno de esos cambios. Pero normalmente un usuario humano no puede realizar tales acciones paralelas y el negocio simplemente continúa.

Ahora, no acabo de entender su ejemplo, pero parece que simplemente está tratando de abusar del diccionario de sesión. He desarrollado bastantes sitios web basados ​​en Django, me he topado con una serie de problemas relacionados con las limitaciones o errores dentro de Django en sí, pero aún jugar con el dict de sesión de múltiples hilos me parece un ejemplo de libro de texto de uso indebido de la sesión ...

Tal vez podríamos encontrar la solución cuando escriba algo más sobre lo que está tratando de lograr.

0

Según lo mencionado por @Krumelur, los subprocesos de Python no se ejecutarán al mismo tiempo debido al bloqueo de interperador global (GIL); es una deficiencia, no una característica, así que no confíe en ello.

La solución actual es crear un subproceso con el multiprocessing module. Puede verificar y ver si un subproceso se está ejecutando utilizando la función is_alive() de la instancia del Proceso. Consulte los documentos para juicy details.

Cuestiones relacionadas