Quais operações são seguras de threads no mapa STD ::?
-
24-09-2019 - |
Pergunta
Suponha que eu tenho:
stl::map<std::string, Foo> myMap;
O seguinte thread de função é seguro?
myMap["xyz"] ?
Ou seja, eu quero ter esse mapa gigante somente leitura que é compartilhado entre muitos tópicos; Mas não sei se a pesquisa é segura.
Tudo está escrito para uma vez primeiro.
Depois disso, vários threads leem dele.
Estou tentando evitar fechaduras para tornar isso o mais faast possível. (yaya possível otimização prematura que eu conheço)
Solução
Em teoria, nenhum recipiente de STL é threadsafe. Na prática, a leitura é segura se o contêiner não estiver sendo modificado simultaneamente. ou seja, o padrão não faz especificações sobre threads. A próxima versão do Will e IIUC padrão garantirá um comportamento reado -reado seguro.
Se você estiver realmente preocupado, use uma matriz classificada com pesquisa binária.
Outras dicas
C ++ 11 exige que todas as funções de membro declaradas como const
são seguros para vários leitores.
Chamando myMap["xyz"]
não é seguro para fios, como std::map::operator[]
não é declarado como const
. Chamando myMap.at("xyz")
é seguro para fios, como std::map::at
é declarado como const
.
Pelo menos na implementação da Microsoft, a leitura de contêineres é segura para threads (referência).
No entanto, std::map::operator[]
pode modificar dados e não é declarado const
. Você deve usar std::map::find
, qual é const
, para conseguir um const_iterator
e desreferente.
Teoricamente, as estruturas e funções de dados somente leitura não requerem bloqueios para a segurança do encadeamento. É inerentemente seguro. Há Sem corridas de dados nas leituras simultâneas da memória. No entanto, você deve garantir inicializações seguras apenas por um único thread.
Como Max S. apontou, principalmente a implementação da leitura de um elemento no mapa como myMap["xyz"]
não teria operações de gravação. Nesse caso, é seguro. Mas, mais uma vez, você deve garantir que não existe um thread que modifique a estrutura, exceto a fase de inicialização.
As coleções de STL não são threadsafe, mas é bastante simples adicionar segurança de threads a um.
Sua melhor aposta é criar um invólucro ThreadSafe em torno da coleção em questão.