std:: map thread-safety
Czy odniesienie do obiektu w std:: map jest bezpieczne?
std::map< std::string, Object > _objects;
Mapa może być zmieniana z wielu wątków i ten dostęp jest zsynchronizowany, ale odniesienie do wartości (obiekt &) jest dostępne tylko z 1 instancji i wątku. czy operacje zapisu z Object i są bezpieczne, jeśli inny wątek doda elementy do mapy? czy to się zmieni?
2 answers
Standard C++11 gwarantuje, że dostęp metody const
do kontenerów jest bezpieczny z różnych wątków (tzn. oba używają metod const
).
Dodatkowo [kontener.wymagania.dataraces] Stany
Implementacje są wymagane, aby uniknąć wyścigów danych, gdy zawartość zawarty obiekt w różnych elementach w tej samej kolejności, excepting
vector<bool>
Innymi słowy, z wyjątkiem vector<bool>
modyfikowanie odrębnej treści nie jest danymi wyścig
Teraz, jeśli jeden wątek unieważnia iterator używany przez inny wątek, wyraźnie jest to wyścig danych (i skutkuje niezdefiniowanym zachowaniem). Jeśli jeden wątek nie ma dostępuconst
do kontenera, a inny nie ma dostępu const
, jest to wyścig danych (i nieokreślone zachowanie). (Uwaga: do celów wielowątkowości " rozważane są funkcje const
", w tym begin
, end
i inne funkcje (i metody), które nie sąconst
po prostu dlatego, że zwracają Iteratory Nie-const
. {[11] } jest zawarty w tym zbiorze pseudo - const
ze względów bezpieczeństwa wątku, z wyjątkiem map
i unordered_set
itd -- 23.2.2.1).
Wydaje się jednak, że jeśli masz odniesienie do elementu w kontenerze i wykonujesz operacje, które nie unieważniają tego odniesienia w innym wątku i nigdy nie zapisują do tego elementu w innym wątku, możesz bezpiecznie odczytać z tego odniesienia. Podobnie, jeśli inne wątki nawet nie czytają z elementu, to pisanie do tego elementu nie powinno powoduje nieokreślone zachowanie.
Dla odniesień do standardów, 17.6.5.9.5 wydaje się gwarantować, że funkcje z biblioteki standardowej nie będą uciekały i niepotrzebnie odczytywały/zapisywały elementy.
Więc krótka odpowiedź: jesteś bezpieczny, o ile drugi wątek nie zadziera bezpośrednio z tym konkretnym wpisem w map
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-25 15:52:24
Elementy na mapie są stabilne, nie są przenoszone ani unieważniane, chyba że element zostanie usunięty z mapy. Jeśli tylko jeden wątek pisze do danego obiektu, a zmiany w samej mapie są poprawnie zsynchronizowane, to wierzę, że będzie to bezpieczne. Jestem pewien, że jest to bezpieczne w praktyce, i myślę, że jest to bezpieczne również w teorii.
Norma gwarantuje, że poszczególne elementy mogą być modyfikowane przez różne wątki, w [kontenerze.wymagania.dataraces]
Niezależnie od (17.6.5.9), implementacje są wymagane, aby uniknąć wyścigów danych, gdy zawartość zawartego obiektu w różnych elementach w tej samej sekwencji, z wyjątkiem
vector<bool>
, są modyfikowane jednocześnie.
Pozwala to jedynie modyfikować elementy, a nie wstawiać nowe elementy do mapy podczas modyfikowania elementów. W przypadku niektórych kontenerów, takich jak std::vector
, modyfikowanie samego wektora może również modyfikować elementy, przenosząc je i przenosząc, ale [asocjacyjne.reqmts] / 9 zapewnia, że std::map
nie unieważni istniejących elementów.
Ponieważ żadna funkcja członka std::map
nie jest wymagana, aby uzyskać dostęp do drugiego członu jego elementów (tj. mapped_type
), myślę, że [res.on.data.races] / 5 mówi, że żaden inny wątek nie będzie kolidował z zapisami do tego użytkownika podczas modyfikowania mapy. (Podziękowania dla Yakka za ostatni element układanki)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-25 15:46:27