Quali operazioni sono thread-safe sulla std :: map?
-
24-09-2019 - |
Domanda
Supponiamo che io sono:
stl::map<std::string, Foo> myMap;
è la seguente thread-safe funzione?
myMap["xyz"] ?
vale a dire. Voglio avere questa mappa gigante di sola lettura che è condivisa tra i molti fili; ma non so se nemmeno cercando è thread-safe.
Tutto è scritto per una volta prima.
Poi, dopo che, più thread leggere da esso.
Sto cercando di evitare blocca per rendere questo come FAAST possibile. (Yaya possibile l'ottimizzazione prematura lo so)
Soluzione
In teoria no contenitori STL sono threadsafe. In pratica lettura è sicuro se il contenitore non viene contemporaneamente modificato. vale a dire lo standard non fa specifiche circa le discussioni. La prossima versione dello standard sarà e IIUC sarà poi garantire un comportamento di sola lettura al sicuro.
Se siete veramente interessati, utilizzare un array ordinato con ricerca binaria.
Altri suggerimenti
C ++ 11 richiede che tutte le funzioni membro dichiarate come const
sono thread-safe per più lettori.
La chiamata myMap["xyz"]
non è thread-safe, come std::map::operator[]
non è dichiarata come const
.
Chiamando myMap.at("xyz")
è però thread-safe, come std::map::at
è dichiarato come const
.
Almeno nella implementazione di Microsoft, la lettura da contenitori è thread-safe ( di riferimento ).
Tuttavia, std::map::operator[]
può modificare i dati e non è dichiarato const
. Si dovrebbe invece usare std::map::find
, che è const
, per ottenere un const_iterator
e dereferenziarlo.
In teoria, lettura solo le strutture dati e funzioni non richiedono alcun blocco per filo di sicurezza. È intrinsecamente thread-safe. Ci sono Non ci sono gare di dati sulla memoria delle letture simultanee. Tuttavia, è necessario garantire la sicurezza inizializzazione da solo un singolo thread.
Come Max S. ha sottolineato, per lo più implementazione di lettura di un elemento nella mappa come myMap["xyz"]
avrebbe alcuna operazione di scrittura. Se è così, allora è sicuro. Ma, ancora una volta, si deve garantire non v'è alcun thread che modifica la struttura tranne la fase di inizializzazione.
collezioni STL non sono threadsafe, ma è abbastanza semplice per aggiungere la sicurezza dei thread a uno.
La cosa migliore è creare un wrapper threadsafe intorno alla collezione in questione.