Czy możliwe jest - i jeśli jest to rozsądne - użycie sendfile()
(lub jego kuzyna Darwin/BSD) w celu przenoszenia danych bezpośrednio między współdzielonymi obiekt pamięci i plik?Kopiowanie danych z obiektu odwzorowanego w pamięci dzielonej przy użyciu funkcji sendfile()/fcopyfile()
Funkcje takie jak sendfile()
i fcopyfile()
może wykonywać wszystkie mechanicznych potrzeb leżących u podstaw takich transferów danych całkowicie bez wychodzenia kernel-przestrzeń - można przejść wzdłuż dwóch otwartych deskryptorów, źródła i miejsca przeznaczenia, podczas wywoływania tych funkcji, i biorą go stamtąd.
Inne środki kopiowania danych niezmiennie wymagają ręcznego manewrowania przez granicę między przestrzenią jądra i przestrzenią użytkownika; takie przełączniki kontekstu są z natury dość kosztowne, pod względem wydajności.
Nie mogę znaleźć niczego definitywnego na temat użycia deskryptora pamięci dzielonej jako argumentu w następujący sposób: brak artykułów za lub przeciw praktyce; nic na odpowiednich stronach; żadne tweety publicznie nie biorą pod uwagę sendfile()
- szkodliwe są deskryptory pamięci dzielonej; & c ... Ale tak, myślę, że powinien być w stanie zrobić coś takiego:
char const* name = "/yo-dogg-i-heard-you-like-shm"; /// only one slash, at zero-index
int len = A_REASONABLE_POWER_OF_TWO; /// valid per shm_open()
int descriptor = shm_open(name, O_RDWR | O_CREAT, 0600);
int destination = open("/tmp/yodogg.block", O_RDWR | O_CREAT, 0644);
void* memory = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, descriptor, 0);
off_t bytescopied = 0;
sendfile(destination, descriptor, &bytescopied, len);
/// --> insert other stuff with memset(…), memcopy(…) &c. here, possibly
munmap(memory, len);
close(descriptor); close(destination);
shm_unlink(name);
... Jest to błędne, lub ważny technika?
A jeśli to drugie, czy można dostosować rozmiar udostępnionej mapy w pamięci przed skopiowaniem danych?
EDYCJA: Rozwijam projekt, którego dotyczy to zapytanie na temat systemu MacOS 10.12.4; Dążę do tego, aby działał pod Linuksem, z ewentualną interoperacyjnością FreeBSD.
Co się stało, gdy próbowałeś? – EJP
@EJP Nie próbowałem tego dokładnego schematu - 3-uderzeniowe uderzenie combo 'shm_open()', 'mmap (..., MAP_SHARED, ...)' i 'sendfile()' - jeszcze z dwóch powodów. Po pierwsze, pomniejszy punkt: jestem teraz rozwijający się natywnie na macOS, więc mój 'sendfile()' jest polyfill przy użyciu 'fcopyfile()' ... po drugie: moje bieżące zadanie polega na zaimplementowaniu dostępu do mapowanej pamięci przez odwzorowanie jej pamięci klasa wrapper (które to opakowanie oferuje już tylko mapy pamięci tylko do odczytu, qv https://github.com/fish2000/libimread/blob/master/src/file.cpp#L115-L140); Będę używał tego, czego się nauczyłem, robiąc to i z SO, na problemie z dzieloną pamięcią. – fish2000