[Python] aggiungere o distruggere una locked item in un dict mentre un'altro thread o asyncio lo legge/scrive per un'altra item?

Manlio Perillo manlio.perillo a gmail.com
Gio 11 Feb 2016 19:51:33 CET


2016-02-11 19:07 GMT+01:00 alessandro medici <alexxandro.medici a gmail.com>:
> Intanto grazie mille della risposta cortese e soprattutto davvero molto
> utile in particolare ed in generale.
>
> Peccato solo che manchi il caso dict.__delitem__(item)
>

Vale lo stesso discorso degli altri.

> Si, in effetti uso asyncio in un thread, ma altri thread lavorano al
> contempo sugli stessi dizionari e mi risulta che che Gil si sganci quando
> entra in un thread.
>

Dalla pagina che ho linkato:
"The Global Interpreter Lock (GIL) is used internally to ensure that
only one thread runs in the Python VM at a time"
e
'In general, Python offers to switch among threads only between
bytecode instructions"

Quindi se un thread legge un valore di un dizionario mentre altri ne
modificano il valore o lo cancellano,
in linea di massima puoi assumere che le operazioni vengono eseguite
in modo seriale, una alla volta.
Quello che non sai è l'ordine in cui vengono eseguiti, ma non dovrebbe
interessarti.

> Per locked intendo l'usare una context manager (di massima
> multiprocessing.Lock: è atomica e perfettamente with compatibile :-) ma
> riferita solo all'item specifica del dizionario su cui il thread sta
> lavorando, con questo è ovvio che potrei segnalare a tutti i thread di
> lasciare in pace i dizionari ove altri thread stanno lavorando, ma il tutto
> mi rallenterebbe troppo il flusso del programma.
>

No, non puoi proteggere con un lock un solo item ma devi proteggere
l'intero dizionario.
Questo perchè il dizionario è una struttura complessa.
Il caso era diverso se usavi un array (array di dimensione fissa, non una list).

Il tuo problema dovrebbe essere il classico:
https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem
che si può risolvere con reader-writer lock.

Però non è disponibile nella libreria standard di Python (ma trovi
qualcosa se cerchi con google); inoltre non saprei dirti se va bene
nel tuo caso dato che non ho molta esperienza nel loro uso.

> [...]
> In questo momento quindi mi stavo scrivendo un programma che andasse a
> vedere in pratica cosa potrebbe succedere: l'idea sarebbe forzare collisioni
> sullo stesso dizionario di solo sei item mettendo su quattro thread che
> random leggono/scrivono/cancellano/aggiungono.
>

Un solo thread alla volta accederà al dizionario.
Con Jython potresti invece avere problemi.


Ciao  Manlio


Maggiori informazioni sulla lista Python