2009-12-23 11 views
8

Potrzebujemy wielu programów do wywoływania funkcji we wspólnej bibliotece. Biblioteka umożliwia dostęp i aktualizację wspólnej pamięci globalnej. Wywołania funkcji każdego programu wymagają obejrzenia tej wspólnej pamięci globalnej. To jest jedno wywołanie funkcji, aby zobaczyć aktualizacje jakiegokolwiek wcześniejszego wywołania funkcji, nawet jeśli wywołane z innego programu. Ze względu na kompatybilność mamy kilka ograniczeń projektowych, w jaki sposób funkcjonuje odsłonięte przez udostępnionej biblioteki musi działać:Tworzenie obiektów w pamięci współdzielonej C++

  • Wszelkie elementy danych (zarówno standardowych typów danych i obiektów), które są zadeklarowane globalnie musi być widoczna dla wszystkich rozmówców, niezależnie od wątek, w którym działa kod.
  • Wszystkie elementy danych, które są zadeklarowane lokalnie w funkcji, są widoczne tylko wewnątrz tej funkcji.
  • Dowolny standardowy typ danych lub wystąpienie dowolnej klasy może być wyświetlane lokalnie lub globalnie lub w obu przypadkach.

Jednym z rozwiązań jest umieszczenie wspólnej pamięci bibliotecznej biblioteki w nazwanej pamięci współdzielonej. Pierwsze wywołanie biblioteki utworzy nazwaną pamięć współużytkowaną i zainicjuje ją. Kolejne wywołania programu otrzymają adres pamięci współdzielonej i wykorzystają ją jako wskaźnik do globalnej struktury danych. Obiekty globalnie zadeklarowane muszą być dynamicznie przydzielane w pamięci współdzielonej, podczas gdy instancje obiektów zadeklarowane lokalnie mogą być umieszczane na stosie lub w lokalnym stosie wątku wywołującego. Pojawiają się problemy, ponieważ zainicjalizowane obiekty w pamięci globalnej mogą tworzyć i wskazywać pod-obiekty, które przydzielają (nową) dodatkową pamięć. Te nowe przydziały również muszą znajdować się we wspólnej pamięci i powinny być widoczne dla wszystkich wywoływaczy bibliotek. Kolejną komplikacją są obiekty, które zawierają ciągi, pliki itp., Mogą być również używane w programie wywołującym. Po zadeklarowaniu w programie wywołującym pamięć obiektu jest lokalna dla programu wywołującego, a nie współdzielona. Zatem kod obiektu musi obsłużyć dowolny przypadek. Wydaje nam się, że rozwiązanie będzie wymagać zastąpienia globalnego umieszczania nowych, regularnych nowych i usuwania operatorów. Znaleźliśmy projekt systemu zarządzania pamięcią, który wygląda na to, że będzie działał, ale nie znaleźliśmy żadnych rzeczywistych implementacji. Jeśli ktoś wie o implementacji projektu zarządzania pamięcią Nathana Myersa (http://www.cantrip.org/wave12.html?seenIEPage=1), byłbym wdzięczny za link do niego. Ewentualnie, jeśli ktoś wie o innym współdzielonym menedżerze pamięci, który uwzględnia dynamiczne przydzielanie obiektów, chciałbym o tym wiedzieć. Sprawdziłem biblioteki Boost i wszystkie inne źródła, które mogę znaleźć, ale nic nie wydaje się robić tego, czego potrzebujemy. Wolimy nie pisać samemu. Ponieważ wydajność i solidność są ważne, dobrze byłoby użyć sprawdzonego kodu. Z góry dziękuję za wszelkie pomysły/pomoc.

Dziękujemy za sugestie dotyczące bibliotek ATL i OSSP. Sprawdzam je teraz, chociaż obawiam się, że ATL jest zbyt Wincentykiem, jeśli celem okaże się być Unix.

Jeszcze jedno wydaje nam się jasne. Ponieważ obiekty mogą być tworzone dynamicznie podczas wykonywania, schemat zarządzania pamięcią musi być w stanie przydzielić dodatkowe strony pamięci współużytkowanej. Teraz zaczyna wyglądać jak pełnowymiarowy menedżer pamięci zastępujący sterty.

+2

Czy nie jest to kanoniczne rozwiązanie problemu z utworzeniem serwera, z którego mogą korzystać aplikacje klienckie? O wiele łatwiejsze niż pomieszanie z pamięcią wspólną, która jest mało prawdopodobna z przyczyn, które dajesz. –

+0

Uzgodnione z Neilem. – wheaties

+0

Tak. Przeprojektowanie aplikacji byłoby najprostszym sposobem rozwiązania problemu. Niestety ze względu na ograniczenia projektowe wynikające z kompatybilności z innymi komponentami nie mamy takiej opcji. – BillC

Odpowiedz

0

OSSP mm - wspólna Alokacja pamięci:

man 3 mm

1

Spójrz na boost.interprocess.

+1

Jak wspomniałem we wpisie, przyjrzeliśmy się bibliotece Boost. Niestety nie osiągnęliśmy tego, czego potrzebowaliśmy. Doprowadziło nas to do obiecujących zasobów, takich jak link, o którym wspomniałem w poście. – BillC

0

Na pewno znalazłeś, jest to bardzo złożony problem i bardzo trudny do prawidłowego wdrożenia. Kilka wskazówek z moich doświadczeń. Przede wszystkim zdecydowanie chcesz zsynchronizować dostęp do alokacji pamięci współużytkowanej za pomocą semaforów. Po drugie, wszelkie modyfikacje obiektów współużytkowanych za pomocą wielu procesów muszą być również chronione semaforami.Na koniec, musisz myśleć w kategoriach przesunięć od początku obszaru pamięci współdzielonej, a nie bezwzględnych wartości wskaźnika, podczas definiowania obiektów i struktur danych (generalnie możliwe jest odwzorowanie pamięci pod innym adresem w każdym dołączonym procesie , chociaż możesz wybrać stały adres mapowania, jeśli potrzebujesz). Złożenie wszystkiego razem w solidny sposób jest trudną częścią. Struktura danych współdzielonych na pamięć może łatwo ulec uszkodzeniu, jeśli proces powinien niespodziewanie umrzeć, dlatego zazwyczaj wymagany jest mechanizm czyszczenia/odzyskiwania.

+0

Masz dokładnie rację. Problem jest złożony i dlatego nie chcemy pisać kodu od zera. – BillC

0

Zbadaj także muteksy i semafory. Kiedy dwie lub więcej jednostek potrzebuje współużytkować pamięć lub dane, musi istnieć mechanizm "sygnalizacji ruchu", który ogranicza dostęp do zapisu tylko jednemu użytkownikowi.

+0

Dzięki. Rozumiemy, że musi to być bezpieczne dla wątków i zaimplementowane muteksy w celu kontrolowania dostępu. Głównym problemem, jaki mamy, jest zapewnienie, że niektóre obiekty są przydzielane w pamięci współdzielonej wraz z obiektami, które tworzą, podczas gdy inne wystąpienia tych samych obiektów są przydzielane lokalnie. – BillC

+0

Proces mieszania - pamięć lokalna i dzielona, ​​tak jak opisujesz, wydaje się generalnie jak przepis na katastrofę. Zdefiniowanie bardziej formalnego protokołu komunikacji między procesami jest prawdopodobnie lepszym rozwiązaniem. –

Powiązane problemy