W szczególności szukam kolejki blokującej. Czy jest coś takiego w C++ 11? Jeśli nie, jakie są moje inne opcje? Naprawdę nie chcę już więcej wchodzić w poziom wątku. Zbyt podatny na błędy.Czy są jakieś współbieżne pojemniki w C++ 11?
Odpowiedz
According to Diego Dagum from Microsoft's Visual C++ Team:
pytanie o charakterze powtarzającym się (no, jednym z wielu) jest o pojemnikach STL i czy są bezpieczne dla wątków.
Biorąc słowa Stephana tutaj, w rzeczywistości jest to, że nie są one, a nie jako bug ale jako cechę: każdy mający funkcję składową każdego kontenera STL przejmującej wewnętrzną blokadę by zniszczyć wydajność. Jako uniwersalna biblioteka wielorazowego użytku, w rzeczywistości nie zapewni on poprawności: poprawny poziom umieszczania blokad to określony przez program. W tym sensie poszczególne funkcje składowe nie mają zazwyczaj takiego właściwego poziomu.
The Parallel Patterns Library (PZP) zawiera wiele pojemników, które zapewniają bezpieczny dostęp do gwintu na ich elementy:
- concurrent_vector Class jest sekwencją klasy pojemnik, który umożliwia swobodny dostęp do każdego elementu. Pozwala na bezpieczne współbieżne dołączanie, dostęp do elementu, dostęp do iteratora i operacje przejścia iteratora.
- concurrent_queue Class jest klasą kontenerów sekwencji, która umożliwia dostęp do jej elementów po raz pierwszy, pierwszy z zewnątrz. Umożliwia on ograniczony zestaw bezpiecznych operacji, takich jak push i try_pop, aby wymienić tylko kilka.
Niektóre próbki here.
Również interesująca: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html.
yeach. ale problemem jest - to tylko dla windows = ( –
Interfejsy kontenerów po prostu nie zostały zaprojektowane w tym celu. Dla interfejsów, z których korzystają, blokada widoczna dla klienta jest naprawdę jedynym sposobem, w jaki można to osiągnąć, gwarantując jednocześnie poprawność i przewidywalne zachowanie. Byłoby to również bardzo nieefektywne, ponieważ liczba przejęć byłaby bardzo wysoka (w stosunku do dobrej realizacji).
Roztwór 1
Pass od wartości (w razie potrzeby).
Rozwiązanie 2
Utwórz kolekcję proste przykręcane implementacji, których można użyć, aby przejść pojemników trzymając blokadę Zakres (rozważyć to pseudo C++):
template <typename TCollection>
class t_locked_collection {
public:
t_locked_collection(TCollection& inCollection, t_lock& lock) : collection(inCollection), d_lock(lock), d_nocopy() {
}
TCollection& collection;
// your convenience stuff
private:
t_scope_lock d_lock;
t_nocopy d_nocopy;
};
następnie rozmówcy łączy zamek z kolekcją, a następnie aktualizujesz swoje interfejsy, aby użyć (przekazać) typu kontenera tam, gdzie to właściwe. To tylko rozszerzenie klasy biednego człowieka.
Ten zamknięty pojemnik jest prostym przykładem i istnieje kilka innych wariantów.To jest wybrana przeze mnie droga, ponieważ naprawdę pozwala na użycie poziomu ziarnistości, który jest idealny dla twojego programu, nawet jeśli nie jest tak przejrzysty (syntaktycznie) jak zablokowane metody. Stosowanie istniejących programów jest stosunkowo łatwe. Przynajmniej zachowuje się w przewidywalny sposób, w przeciwieństwie do kolekcji z wewnętrznymi zamkami.
Innym wariantem byłoby:
template <typename TCollection>
class t_lockable_collection {
public:
// ...
private:
TCollection d_collection;
t_mutex d_mutex;
};
// example:
typedef t_lockable_collection<std::vector<int> > t_lockable_int_vector;
... gdzie to typ podobny do t_locked_collection
mogłyby zostać wykorzystane w celu odsłonięcia kolekcji podstawowej. Nie oznacza to, że podejście to jest niezawodne, po prostu głupie.
z "przekazać według wartości", ponieważ masz zamiar przekazać kompletny pojemnik według wartości w celu utworzenia kopii i pracy na kopii? Lub przekazać elementy pojemnika przez wartość? Proszę opracować – steffen
@steffen przekazuje elementy kontenera według wartości, biorąc pod uwagę interfejs wielu kontenerów, to (** Rozwiązanie 1 **) jest dalekie od optymalnego rozwiązania, podejście to jest również prawie bezużyteczną poprawnością wrt, chyba że jesteś skłonny napisać tony obsługi wyjątków i używaj mnóstwa współdzielonych wskaźników – justin
C++ 11 nie dostarcza samodzielnie pojemników jednocześnie. Istnieją jednak opcje biblioteczne. Oprócz wspomnianej już licencji PPL, nie zapomnij o bibliotece Intel TBB.
Ma jednoczesną implementację queue
, hash_map
, , set
i vector
. Ale to nie tylko bezpieczna dla wątków biblioteka kontenerów, ale także równoległa wersja standardowych algorytmów (pętla for, redukcja, sortowanie, ...).
Czy możesz podać mi link współbieżnego zestawu? – user
Dziwię się, że nikt nie wspomniał moodycamel::ConcurrentQueue. Używamy go od dłuższego czasu i działa bardzo dobrze. Specyficzne jest to, że jego wdrożenie jest bezpieczne, co natychmiast przynosi ogromną prędkość. Inne powody jego używania (cytowanie z oficjalnej strony):
Nie ma zbyt wielu pełnowymiarowych kolejek wolnych od blokady dla C++. Wzmocnienie ma jeden, ale jest ograniczony do obiektów z trywialnymi operatorami przypisania i trywialnych destruktorów, na przykład. Kolejka TBB Intela nie jest wolna od blokady i wymaga również trywialnych konstruktorów. Istnieje wiele prac naukowych, które implementują blokady w C++, ale użyteczny kod źródłowy jest trudny do znalezienia, a testy jeszcze bardziej.
Niektóre odniesienia i porównania są dostępne here, here i here.
Problem z implementacją moodycamel polega na tym, że nie jest to FIFO (tj. kolejność popped elementów nie jest gwarantowana tak jak kolejność pchanych elementów), więc nie jest to rozwiązanie uniwersalne. –
- 1. Czy są jakieś "wzorce projektowe" w C?
- 2. Czy są jakieś sytuacje, w których kod miałby sekwencję w C++ 11, ale nie C++ 03?
- 3. W C, Ogólne pojemniki lub bezpieczne pojemniki?
- 4. Czy standardowe kontenery C++ 11 są "ostateczne"?
- 5. Czy są jakieś add_days w datach ruby?
- 6. Co to są pojemniki w Javie
- 7. Czy są jakieś solidne implementacje dużych liczb całkowitych w C?
- 8. Czy są jakieś .NET ESB?
- 9. Czy są jakieś powszechnie stosowane implementacje IQueryable?
- 10. Czy dostępne są jakieś biblioteki ccTalk?
- 11. Czy są jakieś dobre agregatory wiadomości C#, .net?
- 12. Czy są jakieś różnice między "zsynchronizowaną" Javą i "blokadą" C#?
- 13. współbieżne ArrayList
- 14. Czy są jakieś bezpłatne edytory XSL-FO?
- 15. Czy są tam jakieś narzędzia kodu DRYer?
- 16. Czy są dostępne jakieś implementacje filtrów Bloomiera?
- 17. Czy są jakieś dobre alternatywy dla WebSVN?
- 18. Czy są jakieś "anomalie" porównania zmiennoprzecinkowe?
- 19. Czy są jakieś bezpłatne biblioteki klasy OpenCV?
- 20. Czy są jakieś narzędzia Lint XSL?
- 21. Czy są jakieś standardy zwane GUI?
- 22. Czy są jakieś alternatywy do SDK BoxedApp?
- 23. Czy są dostępne jakieś godne alternatywy CSLA?
- 24. Czy są jakieś alternatywy dla XmlUnit?
- 25. Czy są dostępne jakieś dobre geoparsery otwarte?
- 26. Czy znasz jakieś biblioteki C++ w Voxelu?
- 27. ReactJS współbieżne setState wyścigu
- 28. Czy są jakieś standardy kodowania dla JavaScript?
- 29. Czy są jakieś alternatywne prace Cron?
- 30. Czy są jakieś implementacje multiset dla .Net?
+1, Interesujący Q.Scott Meyers zapytał o to w C++ 0x dni [tutaj] (http://www.velocityreviews.com/forums/t732306-concurrent-containers.html) .To byłoby interesujące wiedzieć jak to zmieniło się po C++ 11. –
Bardzo łatwo zmienić kolejkę standardową w kolejkę blokującą za pomocą prymitywów –