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.
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. –
Uzgodnione z Neilem. – wheaties
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