Sono stato inserito in questo video:
Per link
Perché ho fatto questa domanda:
Contrassegnare una classe std::mutex
come mutable
è la risposta giusta alla mia domanda originale e il video è una discussione eccellente e divertente in merito. Sono grato di glampert.
Tuttavia non sono d'accordo con la premessa del discorso che " const
== thread-safe" (vedi punto 16:00).
Di seguito è la mia proposta su come dovremmo interpretare const
in un mondo a più thread. Non è semplice come la proposta di Herb ma (ammettiamolo) se pensi che una qualsiasi delle risposte in multi-threading sia semplice, hai completamente fallito nel cogliere la sfida del multi-threading.
Commenti per favore. Cosa pensi const
significa per programmi multi-thread? Il suo significato è fondamentalmente cambiato?
const
means logically unmodified by dereferences through theconst
reference in question.Multi-threading footnote #1: In objects that form part of the shared state of a multi-threaded program “logically unmodified” will mean “logically
const
member functions only perform reads on the object” and so any implementation that actually performs writes (such as cached values, instrumentation and even employs synchronization mutexes) needs to adequately make them thread-safe to maintain the ‘logical’ appearance of ‘only reads’.Single-threading footnote : Of course even in a single threaded application
const
is by no means a guarantee that an object won’t change during the lifetime of a givenconst
reference. There may be non-const
references (aliases) and even a single threaded program might use to modify an object which has one or moreconst
references.Multi-threaded footnote #2: That lack of guarantee that an object will not be modified just because there is a
const
reference to it is true in spades for multi-threaded applications. So in many senses – no change there.
Penso che la mia più grande preoccupazione sia che, attraverso sono sicuro che Herb Sutter li confermerebbe come errori terribili, temo che leggere const
come "thread-safe" porti troppo facilmente a:
- L'errore che aggiungendo
std::lock_guard guard(this->mutex)
all'inizio di tutti i metodi e il distruttore di una classe in qualche modo ne fanno un uso 'thread-safe'. - La fallacia che se chiami solo metodi
const
su una classe la tua applicazione abbia una garanzia thread-safe e, in caso contrario, puoi presentare un reclamo al responsabile dell'implementazione. - Infine, l'errore è che se non modifichi alcun
mutable
membri e non butti viaconst
ovunque non ti devi preoccupare della sicurezza dei thread perché (apparentemente) "const
significa thread -safe”.
Fallacy 1 è meglio esemplificato supponendo che tu possa avere un senso iterando attraverso una collezione che viene modificata da un altro thread solo perché sai che i metodi sono protetti da lock.
Fallacy 2 spinge un onere potenzialmente oneroso (e persino impossibile) agli implementatori che possono (ovviamente) aggiungere guardie di blocco a tutti i loro metodi ma possono (nel migliore dei casi) perdere tempo e (nel peggiore dei casi) limitarti a configurarti per errore 1.
Fallacy 3 è l'errore che la sicurezza del thread è tutta una questione di concorrenza per l'accesso simultaneo. Tuttavia, il caching della memoria significa che per ottenere uno stato coerente all'interno di un metodo const
, può essere comunque richiesto di garantire che sia stata eseguita una sorta di barriera di memoria (ad esempio almeno "acquisisci").