Mam klasy wątków, z których chciałbym od czasu do czasu uzyskać wskaźnik zmiennej instancji. Chciałbym, aby ten dostęp był chroniony przez muteks, aby wątek był zablokowany przed dostępem do tego zasobu, dopóki klient nie zakończy pracy z jego wskaźnikiem.Jak utworzyć inteligentny wskaźnik, który blokuje i odblokowuje muteks?
Moim początkowym podejściem do tego jest zwrócenie pary obiektów: jednego wskaźnika do zasobu i jednego shared_ptr do obiektu blokady na muteksie. Ten shared_ptr zawiera jedyne odniesienie do obiektu blokady, więc muteks powinien zostać odblokowany, gdy wykracza poza zakres. Coś takiego:
void A::getResource()
{
Lock* lock = new Lock(&mMutex);
return pair<Resource*, shared_ptr<Lock> >(
&mResource,
shared_ptr<Lock>(lock));
}
To rozwiązanie jest mniej niż idealne, ponieważ wymaga, aby klient trzymał się całej pary obiektów. Zachowanie w ten sposób łamie bezpieczeństwo wątku:
Resource* r = a.getResource().first;
Ponadto, moja własna implementacja to deadlocking i mam trudności w określeniu, dlaczego, więc nie może być inne rzeczy złego.
Co chciałbym mieć, to shared_ptr, która zawiera blokadę jako zmienną instancji, wiążąc ją ze środkami dostępu do zasobu. To wydaje się być czymś, co powinno mieć ustalony wzorzec projektowy, ale po przeprowadzeniu pewnych badań jestem zaskoczony, że napotykam go dość trudno.
Moje pytania są następujące:
- Czy istnieje wspólna realizacja tego wzoru?
- Czy są problemy z umieszczeniem muteksu wewnątrz pliku shared_ptr, którego nie pamiętam, co uniemożliwia rozpowszechnienie tego wzorca?
- Czy istnieje dobry powód, aby nie implementować mojej własnej klasy shared_ptr do implementacji tego wzorca?
(NB pracuję na kodzie, który używa Qt, ale niestety nie można używać impuls w tym przypadku. Jednak odpowiedzi obejmujące impuls są nadal w ogólnym interesie.)
Obie odpowiedzi od riv i Jonanthan Wakely są interesujące i godne naśladowania. Idę z Rizem tylko dlatego, że miło jest mieć jakiś kompletny wspólnie edytowany kod w odpowiedzi. –