2017-07-24 10 views
8

W poniższym kodzie, jeśli nie wypuszczę a1, kod wydaje się utknąć w nieskończonej pętli wewnątrz funkcji map.find.Dlaczego nie mogę mieć dwóch akcesorów dla tego samego elementu w mapie skrótu tbb?

Co zrobić, jeśli muszę wyszukać element w dwóch różnych częściach aplikacji?

#include <iostream> 
#include "tbb/concurrent_hash_map.h" 

using namespace std; 
using namespace tbb; 

void main() 
{ 
    concurrent_hash_map<int, int> map; 

    concurrent_hash_map<int, int>::accessor a1, a2; 

    map.insert(make_pair(1, 111)); 

    cout << "a1 - " << map.find(a1, 1) << endl; 

    //a1.release(); 

    cout << "a2 - " << map.find(a2, 1) << endl; 
} 

Odpowiedz

8

akcesor umożliwia dostęp zapisu. Oznacza to, że została uzyskana blokada zapisu i jest przechowywana tylko przez jeden akcesor. Wprowadzasz zakleszczenie, ponieważ ten sam wątek próbuje zablokować ten sam element do zapisu za pośrednictwem różnych akcesorów.

Jeśli chcesz tylko odczytać dane, a następnie użyć const_accessor z find. Nabędzie tylko blokadę odczytu. Wiele blokad odczytu można uzyskać i trzymać bez blokady.

concurrent_hash_map<int, int>::const_accessor a1, a2; 
+0

Dziękuję bardzo! – Jack

+0

Czy jest możliwe posiadanie jednego const_accessor i jednego accessora w tym samym czasie? – Jack

+1

@Jack - No. A Zapis musi nastąpić, gdy nikt nie czyta, aby uniknąć zniekształcenia ich odczytanych danych. Dlatego nie można uzyskać blokady odczytu, gdy istnieje blokada zapisu i na odwrót. W jednym wątku znowu będziesz zaklinowany, jeśli obydwaj użytkownicy spróbują uzyskać dane bez ich zwalniania. Pomysł ze wszystkimi akcesorami polega na użyciu ich w małych blokach, aby nie "przylgnąć" do zamka dłużej, niż jest to wymagane. Const są tylko optymalizacją dla przypadku, w którym synchronizacja nie jest wymagana (wszyscy tylko czytają, a nie zapisują). – StoryTeller

Powiązane problemy