Escritura simultánea en el mismo archivo usando hilos y procesos.

¿Cuál es la solución correcta para estar seguro de que el archivo nunca se dañará al usar muchos procesos y subprocesos?

Versión para hilos, que cuidan los errores de apertura.

lock = threading.RLock() with lock: try: f = open(file, 'a') try: f.write('sth') finally: f.close() # try close in any circumstances if open passed except: pass # when open failed 

para los procesos que supongo debe usar multiprocesamiento.

pero si quiero 2 procesos, y el primer proceso posee 2 hilos (cada uno usa un archivo)

solo hay teoría, pero quiero saber cómo mezclar la sincronización con subprocesos y procesos. ¿Los hilos son “heredados” del proceso ?, ¿por lo que solo se requiere la sincronización entre procesos?

    y 2. No estoy seguro de si el código anterior necesita un bash nested en caso de que la escritura falle, y queremos que el archivo se abra (lo que si se mantendrá abierto después de liberar el locking)

    Si bien esto no queda completamente claro en los documentos , los primitivos de sincronización de multiprocesamiento también sincronizan los subprocesos.

    Por ejemplo, si ejecuta este código:

     import multiprocessing import sys import threading import time lock = multiprocessing.Lock() def f(i): with lock: for _ in range(10): sys.stderr.write(i) time.sleep(1) t1 = threading.Thread(target=f, args=['1']) t2 = threading.Thread(target=f, args=['2']) t1.start() t2.start() t1.join() t2.join() 

    … la salida siempre será 1111111111222222222 o 22222222221111111111 , no una mezcla de las dos.

    Los lockings se implementan sobre los objetos de sincronización del kernel de Win32 en Windows, los semáforos en plataformas POSIX que los admiten y no se implementan en absoluto en otras plataformas. (Puede probar esto con import multiprocessing.semaphore , que generará ImportError en otras plataformas, como se explica en la documentación).


    Dicho esto, es seguro tener dos niveles de lockings, siempre y cuando siempre los use en el orden correcto, es decir, nunca agarre la threading.Lock menos que pueda garantizar que su proceso tenga el multiprocessing.Lock .

    Si lo hace lo suficientemente inteligente, puede tener beneficios de rendimiento. (Los lockings de proceso cruzado en Windows, y en algunas plataformas POSIX, pueden ser órdenes de magnitud más lentas que los lockings dentro del proceso).

    Si lo hace de la manera obvia (solo with threadlock: dentro with processlock: bloque de proceso with processlock: bloques), obviamente no ayudará al rendimiento y, de hecho, ralentizará un poco las cosas (aunque posiblemente no sea suficiente para medir), y No agregará ningún beneficio directo. Por supuesto, sus lectores sabrán que su código es correcto, incluso si no saben que multiprocessing lockings de multiprocessing funcionan entre hilos, y en algunos casos la depuración de los interlockings entre procesos puede ser mucho más fácil que la depuración de interlockings entre procesos … pero no creo que ninguno Es una buena razón para la complejidad adicional en la mayoría de los casos.