[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 20:38:29 CET
2016-02-11 19:51 GMT+01:00 Manlio Perillo <manlio.perillo a gmail.com>:
> [...]
> 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.
>
Forse un esempio può essere più chiaro.
Supponi che il thread A esegua l'istruzione `d['a']`, mentre il thread
B l'istruzione `del d['a']`.
In un programma "corretto" sai che alla fine delle due istruzioni, la
chiave 'a' non sarà più nel dizionario.
Inoltre d['a'] potrebbe o no sollevare un KeyError.
Senza il GIL, invece, se `d['a']` viene eseguita contemporaneamente a
`del d['a']`, allore il programma potrebbe crashare.
Ora considera quest'altro esempio, dove d = {'a': 10}.
Il thread A esegue l'istruzione
d['a'] = d['a'] + 1
mentre il thread B esegue
d['a'] = d['a'] + 3
In un programma "corretto" alla fine delle due istruzioni, d['a'] avrà
il valore 14.
Quello che non sai è il valore di `d['a']` durante le due operaazioni.
Senza sincronizzazione, però, quello che può succedere è:
- il thread A esegue `d['a']` ed ottiene 10
- il controllo passa al thread B che esegue `d['a']` ed ottiene 10
- il thread B quindi esegue `d['a'] = 13`
- il controllo passa al thread A che esegue `d['a'] = 11`
Quindi alla fine d['a'] avrà il valore 11, oppure potresti ottenere
13, o, infine, il valore corretto 14.
Il GIL serve a prevenire crash quando deve essere aggiornata una
struttura dati implementata in C e manipolata dalla VM, ma non
garantisce la corretta sincronizzazione delle operazioni scritte in
Python.
Puoi scrivere uno script che controlli se quello che ho descritto
avviene veramente.
Io non ho controllato, ma sono curioso.
L'esempio che ho fatto è il classico problema del trasferimento su
conto bancario:
http://c2.com/cgi/wiki?BankAccountTransferProblem
Stranamente non c'è su wikipedia, forse non è tanto classico.
> [...]
Ciao Manlio
Maggiori informazioni sulla lista
Python