Const significa thread-safe? [chiuso]

4

Sono stato inserito in questo video:

link

Per link

Perché ho fatto questa domanda:

link

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 the const 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 given const reference. There may be non-const references (aliases) and even a single threaded program might use to modify an object which has one or more const 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:

  1. 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'.
  2. 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.
  3. Infine, l'errore è che se non modifichi alcun mutable membri e non butti via const 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").

    
posta Persixty 26.02.2015 - 12:57
fonte

3 risposte

4

Sebbene const come funzione del linguaggio non garantisca la sicurezza del thread, molte delle funzioni costanti, per loro natura, sono thread-safe in quanto di solito leggono alcune variabili costanti, calcolano un risultato e lo restituiscono. Questa è la costante bit a bit menzionata nel video. I casi in cui è necessaria la sincronizzazione interna (credo) sono in minoranza.

Lo si vede da solo crea un (falso) sentimento di sicurezza in un programmatore che pensa intuitivamente che una funzione sia protetta da un blocco perché è costante.

Quindi sostengo personalmente la convenzione, che se una funzione è costante, ma non costante per bit, sincronizzarla internamente per renderla protetta da un thread, perché i potenziali utenti si aspettano che sia.

Questa convenzione è seguita nel STL come menzionato nella presentazione, il che rafforza ulteriormente l'espirazione degli utenti.

The fallacy that if you only call const methods on a class your application has a thread-safe guarantee and you can complain to the implementer if not.

Credo che questo sia inteso. Come utente di una libreria, non causa alcun danno se si presta attenzione a questo, ma come implementatore di una libreria è meglio seguire questa convenzione.

Fallacy 3 is the fallacy that thread-safety is all about competing for simultaneous access. Memory caching however means that to obtain a coherent state within a const method there may still be a requirement to ensure some kind of memory barrier has been performed (e.g. at least “acquire”).

Forse const == thread-safe sarebbe stato scritto meglio come const == > thread-safe. Non credo che l'intenzione di Herb Sutter fosse di affermare che const è l'ultimo proiettile d'argento nella sicurezza del filo. Nella mia interpretazione il messaggio non esiste più, quindi quando scrivi una funzione const , la tua intenzione dovrebbe essere quella di renderlo anche sicuro da thread.

    
risposta data 26.02.2015 - 14:36
fonte
2

Sebbene non significhi thread-safe per sé, per la libreria standard lo fa:

17.6.5.9 Data race avoidance [res.on.data.races]

1 This section specifies requirements that implementations shall meet to prevent data races (1.10). Every standard library function shall meet each requirement unless otherwise specified. Implementations may prevent data races in cases other than those specified below.
2 A C++ standard library function shall not directly or indirectly access objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function’s arguments, including this.
3 A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function’s non-const arguments, including this.
[...]

E questo è il modello che i tipi e le funzioni definiti dall'utente dovrebbero seguire ovunque ragionevolmente possibile.

    
risposta data 27.02.2015 - 00:21
fonte
0

Ad esempio in C ++, una classe const o una struct possono avere membri mutabili. I membri mutabili vengono in genere utilizzati in situazioni in cui il valore logico di un oggetto non cambia, ma la rappresentazione interna è la mia modifica.

Cambiare i membri mutabili ovviamente non è automaticamente thread-safe. Pertanto, l'accesso a oggetti const non è automaticamente thread-safe.

Un altro esempio potrebbe essere una classe che tiene un puntatore a un file. Posso leggere o scrivere da quel file, anche se l'istanza è const. Ma è improbabile che queste operazioni siano thread-safe.

    
risposta data 23.08.2015 - 18:14
fonte

Leggi altre domande sui tag