2010-02-20 10 views
12

Tengo dos hilos, uno que escribe en un archivo, y otro que periódicamente mueve el archivo a una ubicación diferente. La escritura siempre llama al open antes de escribir un mensaje, y llama al close después de escribir el mensaje. El transportador usa shutil.move para hacer el movimiento.Subprocesos múltiples de Python que acceden al mismo archivo

Veo que después de que se realiza el primer movimiento, el escritor ya no puede escribir en el archivo, es decir, el tamaño del archivo siempre es 0 después del primer movimiento. ¿Estoy haciendo algo mal?

Respuesta

25

El bloqueo es una posible solución, pero prefiero la arquitectura general de tener cada recurso externo (incluido un archivo) tratado por un único hilo separado. Otros subprocesos envían solicitudes de trabajo al subproceso dedicado en una instancia Queue.Queue (y proporcionan una cola propia aparte como parte de los parámetros de solicitud de trabajo si necesitan un resultado), el subproceso dedicado pasa la mayor parte del tiempo esperando en un .get en ese cola y cada vez que recibe una solicitud continúa y la ejecuta (y devuelve resultados en la cola pasada si es necesario).

He proporcionado ejemplos detallados de este enfoque, p. en "Python in a Nutshell". Python's Queue es intrínsecamente seguro para subprocesos y simplifica enormemente tu vida.

Entre las ventajas de esta arquitectura es que se traduce sin problemas a multiprocessing si y cuando decide cambiar de un trabajo a un proceso independiente en lugar de un hilo separado (por ejemplo, para tomar ventaja de los múltiples núcleos) - multiprocessing proporciona su propio workalike Queue tipo para hacer una transición suave como la seda ;-).

+0

Si estoy escribiendo un biblioteca que debería ser segura para subprocesos pero que no siempre se usa en subprocesos. ¿Debería tomar este enfoque o mirar un candado? No estoy seguro de si mi biblioteca debería estar generando nuevos hilos si solo se usa un hilo. ¿Cuál es la mejor solución para una cantidad variable de hilos que podría ser uno? –

7

Cuando dos hilos acceden a los mismos recursos, suceden cosas extrañas. Para evitar eso, siempre bloquee el recurso. Python tiene el conveniente threading.Lock para eso, así como algunas otras herramientas (vea la documentación del módulo threading).

4

Salida http://www.evanfosmark.com/2009/01/cross-platform-file-locking-support-in-python/

Se puede utilizar un simple bloqueo con su código, tal como está escrita por Evan Fosmark en una mayor pregunta StackOverflow:

from filelock import FileLock 

with FileLock("myfile.txt"): 
    # work with the file as it is now locked 
    print("Lock acquired.") 

Una de las bibliotecas más elegantes que he visto .

+0

¿Estás seguro de que esto se puede combinar realmente con mover archivos? –

+3

El código de Evan Fosmark se aplica a la sincronización de múltiples * procesos *, no * hilos *. Según la sugerencia de Eli, usaría 'threading.Lock' o' threading.RLock'. –

+0

Como seguimiento, el enlace en esta publicación ya no está funcionando. Por [la respuesta de Evan a una pregunta relacionada aquí] (http://stackoverflow.com/a/498505/760905) también puede encontrar el código en https://github.com/dmfrey/FileLock – MartyMacGyver

Cuestiones relacionadas