Pytanie Czy mogę zmienić rozmiar pamięci współużytkowanej systemu Linux za pomocą shmctl?


Mam aplikację C ++, która przydziela pamięć współużytkowaną w systemie Linux przez shmget (2). Dane, które przechowuję w pamięci współdzielonej, rosną okresowo i chciałbym zmienić rozmiar wspólnej pamięci w sposób analogiczny do sposobu, w jaki realloc () zwiększa zwykłą pamięć. Czy jest jakiś sposób na zrobienie tego? Znalazłem dokument na stronie IBM, który wymienia polecenie SHM_SIZE, ale strony podręcznika Linux i BSD go nie mają, nawet w sekcjach specyficznych dla Linuksa.


11
2018-05-07 16:12


pochodzenie


jako inspirację, spójrz na: boost.org/doc/libs/1_61_0/doc/html/interprocess/... - konkretnie managed_shared_memory które można wykorzystać do przechowywania vector we wspólnej pamięci ... - Nim


Odpowiedzi:


Prosta odpowiedź: nie ma łatwego sposobu.

Powody są dość logiczne. Pamięć współdzielona jest dołączana do przestrzeni wirtualnej każdego procesu indywidualnie. Każdy proces ma swoją własną wirtualną przestrzeń adresową. Każdy proces może dowolnie dołączyć segment (nie dosłownie, wyrównanie wyznacza pewne ograniczenia) dowolny adres. W jaki sposób system może zagwarantować, że, powiedzmy, rozszerzając obszar o 4 MB, każdy "użytkownik" tego segmentu będzie mógł dopasować duży blok pod tym samym adresem początkowym gdzie wcześniej był mniejszy segment?

Ale nie powinieneś się poddawać! Możesz być kreatywny. Możesz wymyślić pomysł posiadania jednego nagłówek segment, w którym przechowujesz informacje o rzeczywistym segmencie ładowności. Możesz sprawić, by każdy proces był zgodny z niektórymi regułami, jak na przykład: załóż odcinek ładunku, gdy jego identyfikator, jak opisano gdzieś w segment nagłówka, nie pasuje znany.

Porada: Podejrzewam, że o tym wiesz, ale nigdy nie przechowuj wskaźników w obrębie współużytkowanego regionu, tylko przesuń.

Mam nadzieję, że wykorzystasz mój bełkot.


7
2018-05-28 07:08



Dziękuję - to bardzo pomocne! - David Lobron


Wydaje mi się, że możesz napisać własnego menedżera pamięci do swojego celu. Koncepcja jest dość prosta:

  1. Masz wspólny blok pamięci, którego rozmiar jest N bajty;
  2. Przydziel nowy blok pamięci współdzielonej za pomocą 2*N rozmiar;
  3. Skopiuj pamięć z jednego bloku do drugiego;
  4. Uwolnij stary blok pamięci współdzielonej;
  5. Zawiń # 2-4 w rutynę i użyj go;

Obawiam się, że nie mamy z tym nic wspólnego. Oto jak std::vector jest zaimplementowane. I void *realloc() w większości przypadków zwróci ci wskaźnik do nowego bloku pamięci (ale nie do rozszerzonego starego bloku).


0
2018-03-24 19:11



Wierzę, że spowoduje to, że "współdzielona" właściwość tego rodzaju pamięci nie będzie istnieć. - GreenScape


Wydaje mi się, że funkcja mremap został wdrożony, aby wykonać to, co chcesz. Musisz tylko sprecyzować w argumentach stary rozmiar i nowy segment pamięci współdzielonej. Jeśli dodasz flagę MREMAP_MAYMOV, w razie potrzeby możesz przenieść segment pamięci współdzielonej (np. Jeśli nie ma wystarczającej ilości wolnego miejsca tuż po starym segmencie pamięci współużytkowanej).

Spójrz na stronę podręcznika: http://man7.org/linux/man-pages/man2/mremap.2.html.


0
2017-07-13 13:11