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?

Author: deeptowncitizen, 2013-02-25

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.

 31
Author: Yakk - Adam Nevraumont,
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)

 12
Author: Jonathan Wakely,
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