¿Cómo harías seguro este hilo de Python Dictionary?

Tengo un servidor web que se ejecuta en Python . El servidor es privado, por lo que solo espero que alrededor de 20 usuarios se conecten a él. El servidor tiene varios subprocesos (8 núcleos en este momento, por lo que supongo 8 hilos).

Cuando llegan las solicitudes, puedo identificar a los usuarios. En algunas consultas, necesito actualizar un dictionary simple con el nombre de usuario del formulario -> Boolean . ¿Cómo podría hacer que este hilo sea seguro?

Si necesitas un candado (para evitar las condiciones de carrera descritas por Joonas), y estás atrapado con Python 2.4,

 import threading lock = threading.Lock() shared_dict = {} def do_thing(user, value): lock.acquire() try: shared_dict[user] = value finally: # Always called, even if exception is raised in try block lock.release() 

Tendrá que crear un objeto de locking global.

 lock = threading.Lock() 

Luego, alrededor de cada acceso del diccionario adquiere y libera el locking. La forma más sencilla de hacerlo es con la nueva (ish) with syntax .

 with lock: dict[key] = value 

Puede o no necesitar usar un locking, dependiendo de cómo se actualice el Boolean .

Si el valor del Boolean no depende de su valor anterior, entonces no se necesita un locking: escribir y leer un diccionario de Python es seguro para subprocesos por sí mismo (excepto: no se permite escribir mientras se está iterando , pero eso no está permitido en un solo hilo) ya sea). La visibilidad de la memoria es similar a lo que se lograría utilizando volatile en algunos idiomas.

Lo que intrínsecamente no es seguro para subprocesos es la secuencia “read-modify-write”, que resulta en una condición de carrera. Si el valor del valor Boolean depende de su valor anterior, entonces tiene que usar un locking, porque de lo contrario el hilo A podría leer el valor primero, luego el hilo B podría cambiarlo y luego A lo cambiaría nuevamente, basándose en un valor obsoleto para empezar.

Use threading.LOCK.acquire () antes de actualizar el diccionario y use threading.LOCK.release (), una vez que haya terminado de actualizarlo.

No necesita bloquear el diccionario para esta operación, porque esta operación es atómica, y GIL se encarga de esto. A menos que tenga operaciones como lectura-cambio-escritura, no se preocupe.