pandas y números de seguridad de hilos

Estoy usando pandas en un servidor web (apache + modwsgi + django) y tengo un error difícil de reproducir que ahora descubrí que se debe a que los pandas no son seguros para subprocesos.

Después de una gran cantidad de reducción de código, finalmente encontré un progtwig independiente corto que se puede usar para reproducir el problema. Puedes verlo abajo.

El punto es: contrariamente a la respuesta de esta pregunta, este ejemplo muestra que los pandas pueden bloquearse incluso con operaciones muy simples que no modifican un dataframe. No puedo imaginar cómo este simple fragmento de código podría ser inseguro con los hilos …

La pregunta es sobre el uso de pandas y numpy en un servidor web. ¿Es posible? ¿Cómo se supone que debo arreglar mi código usando pandas? (Un ejemplo de uso de locking sería útil)

Aquí está el código que causa una falla de segmentación:

 import threading import pandas as pd import numpy as np def let_crash(crash=True): t = 0.02 * np.arange(100000) # ok con 10000 data = pd.DataFrame({'t': t}) if crash: data['t'] * 1.5 # CRASH else: data['t'].values * 1.5 # THIS IS OK! if __name__ == '__main__': threads = [] for i in range(100): if True: # asynchronous t = threading.Thread(target=let_crash, args = ()) t.daemon = True t.start() threads.append(t) else: # synchronous let_crash() for t in threads: t.join() 

Mi entorno: python 2.7.3, numpy 1.8.0, pandas 0.13.1

vea la advertencia en los documentos aquí: http://pandas.pydata.org/pandas-docs/dev/gotchas.html#thread-safety

pandas no es seguro para subprocesos porque el mecanismo de copia subyacente no lo es. Numpy Creo que tiene una operación de copia atómica, pero los pandas tienen una capa encima de esto.

Copiar es la base de las operaciones de pandas (ya que la mayoría de las operaciones generan un nuevo objeto para devolver al usuario)

No es trivial solucionar este problema y tendría un costo de rendimiento bastante alto, por lo que necesitaría un poco de trabajo para solucionarlo correctamente.

Lo más sencillo es simplemente no compartir objetos a través de hilos o bloquearlos en el uso.

Configure mod_wsgi para que se ejecute en un solo modo de subproceso.

 WSGIDaemonProcess mysite processes=5 threads=1 WSGIProcessGroup mysite WSGIApplicationGroup %{GLOBAL} 

En este caso, está utilizando el modo de demonio mod_wsgi para que los procesos / subprocesos se puedan configurar de forma independiente en cualquier Apache MPM que esté utilizando.