2009-12-04 11 views
17

Ho una std :: map che uso per mappare i valori (ID campo) su una stringa leggibile dall'uomo. Questa mappa viene inizializzata una volta quando il mio programma inizia prima che vengano avviati altri thread, dopodiché non viene mai più modificato. In questo momento, do a ogni thread la propria copia di questa (piuttosto grande) mappa ma questo è ovviamente un uso inefficiente della memoria e rallenta l'avvio del programma. Quindi stavo pensando di dare ad ogni thread un puntatore alla mappa, ma questo solleva un problema di sicurezza del thread.Sicurezza filo di std :: map per operazioni di sola lettura

Se tutto quello che sto facendo è la lettura dalla mappa utilizzando il seguente codice:

std::string name; 
//here N is the field id for which I want the human readable name 
unsigned field_id = N; 
std::map<unsigned,std::string>::const_iterator map_it; 

// fields_p is a const std::map<unsigned, std::string>* to the map concerned. 
// multiple threads will share this. 
map_it = fields_p->find(field_id); 
if (map_it != fields_p->end()) 
{ 
    name = map_it->second; 
} 
else 
{ 
    name = ""; 
} 

Sarà questo lavoro o ci sono problemi con la lettura di uno std :: map da più thread?

Nota: Attualmente sto lavorando con Visual Studio 2008, ma mi piacerebbe che funzionasse con le principali implementazioni STL.

Aggiornamento: esempio di codice modificato per la correttezza const.

risposta

16

Questo funzionerà da più thread purché la mappa rimanga la stessa. La mappa che usi è di fatto immutabile, quindi qualsiasi scoperta farà effettivamente una scoperta in una mappa che non cambia.

Qui è un collegamento rilevante: http://www.sgi.com/tech/stl/thread_safety.html

L'attuazione SIG di STL è thread-safe solo nel senso che accessi contemporanei alla distinti contenitori sono sicuri, e simultaneo accessi in lettura al al comune I contenitori sono sicuri. Se più thread accedono a un singolo contenitore e potenzialmente almeno una stringa può scrivere, l'utente è responsabile dell'esclusione reciproca tra i thread durante gli accessi del contenitore.

Si cade nella categoria "accesso in lettura simultanea ai contenitori condivisi".

Nota: questo vale per l'implementazione SGI. È necessario verificare se si utilizza un'altra implementazione. Delle due implementazioni che sembrano ampiamente utilizzate come alternativa, STLPort ha una sicurezza del thread integrata come so. Comunque non so sull'implementazione di Apache.

+1

Nota: La risposta è limitata alla implemenation SGI STL. L'OP non ha menzionato quale è utilizzato. – foraidt

+0

Vero, modifico per aggiungere queste informazioni. – laura

+0

Uso l'implementazione fornita con Visual Studio 2008, ma stavo cercando una risposta che riguardasse la std :: map in generale, o almeno attraverso la maggior parte delle implementazioni, se possibile. –

9

Dovrebbe andare bene. È possibile utilizzare i riferimenti const se si desidera documentare/imporre il comportamento di sola lettura.

Nota che la correttezza non è garantito (in linea di principio la mappa potrebbe scegliere di riequilibrarsi su una chiamata a find), anche se si utilizza metodi const solo (un'implementazione davvero perversa poteva dichiarare l'albero mutabile). Tuttavia, ciò sembra abbastanza improbabile nella pratica.

+0

Considererei un'implementazione con interni mutabili non thread-safe buggy. – hirschhornsalz

+0

Ho aggiornato leggermente il mio codice per utilizzare un riferimento const sulla mappa e un const_iterator –

+0

drhirsch, un'implementazione non a prova di codice potrebbe ancora essere conforme agli standard, ma sarebbe certamente di scarsa qualità. – Useless