2012-06-12 24 views
8

Mam duży bufor:uzyskać zachowanie kopiowanie przy zapisie z widelcem() ING, bez fork()

char *buf = malloc(1000000000); // 1GB 

Gdybym rozwidlony nowy proces, miałoby to buf których pamięci współdzielonej z buf rodzicielski, dopóki jeden lub drugi nie napisał do niego. Nawet wtedy, tylko jeden nowy blok 4KiB musiałby zostać przydzielony przez jądro, reszta byłaby nadal udostępniana.

Chciałbym zrobić kopię buf, ale zmienię tylko trochę kopii. Chciałbym zachować zachowanie kopiowania przy zapisie bez rozwidlania. (Jak za darmo podczas rozwidlenia.)

Czy to możliwe?

+0

oczywiście, ale nie będzie "za darmo" - będziesz musiał zarządzać pamięcią i śledzić zmiany. –

+1

Tak, chcę "za darmo". Zastanawiałem się, czy były jakieś rozwiązania oparte na mmap, a może coś, czego nawet nie wyobrażałem sobie. – fadedbee

+0

Być może mmap z MAP_ANONYMOUS i MAP_PRIVATE wykona zadanie? – fadedbee

Odpowiedz

9

Będziesz chciał utworzyć plik na dysku lub segment pamięci wspólnej POSIX (shm_open) dla bloku. Za pierwszym razem zamapuj je na MAP_SHARED. Kiedy będziesz gotowy do zrobienia kopii i przejdziesz do KOSZYKA, zadzwoń ponownie pod numer mmap z MAP_FIXED i MAP_PRIVATE, aby mapować na górze oryginalnej mapy, a następnie MAP_PRIVATE, aby utworzyć drugą kopię. To powinno dać ci pożądane efekty.

+1

To wygląda bardzo zachęcająco, ale nie mogę go uruchomić. Pojawia się błąd magistrali (w linii 13). fd == 3. Czy mógłbyś wskazać mój głupi błąd? https://gist.github.com/2924412 – fadedbee

+1

Potrzebujesz 'ftruncate', aby nadać segmentowi pamięci wspólnej rozmiar. Początkowy rozmiar wynosi zero. –

+0

Dzięki, dodałem ftruncate i mam teraz segfault zamiast błędu magistrali, ciągle w linii 14. – fadedbee