Возможно ли — и если это так разумно — использовать sendfile()
(или его двоюродного брата Darwin/BSD fcopyfile()
) для передачи данных непосредственно между объектом общей памяти и файлом?
Такие функции, как sendfile()
и fcopyfile()
, могут полностью выполнять все необходимые механистические операции, лежащие в основе такой передачи данных, не покидая пространства ядра — вы передаете два открытых дескриптора, источник и место назначения, при вызове этих функций, и они берут их оттуда.
Другие средства копирования данных неизменно потребуют ручного маневрирования через границу между пространством ядра и пространством пользователя; такие переключения контекста по своей сути довольно затратны с точки зрения производительности.
Я не могу найти ничего определенного по поводу использования дескриптора разделяемой памяти в качестве аргумента: нет статей за или против этой практики; ничего на соответствующих man
-страницах; никаких твитов, публично считающих sendfile()
использование дескрипторов общей памяти вредным; &c... Но я думаю, что смогу сделать что-то вроде этого:
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);
… Это заблуждение или действующий метод?
И если последнее, можно ли настроить размер общей карты в памяти перед копированием данных?
РЕДАКТИРОВАТЬ: я разрабатываю проект, к которому относится этот запрос, на macOS 10.12.4; Я стремлюсь к тому, чтобы он работал на Linux с возможной совместимостью с FreeBSD.
shm_open()
,mmap(…, MAP_SHARED, …)
иsendfile()
— пока по двум причинам. Во-первых, второстепенный момент: прямо сейчас я разрабатываю исходно для macOS, поэтому мойsendfile()
— это полифилл, использующийfcopyfile()
… во-вторых: моя текущая задача — реализовать доступ к отображаемой памяти записываемых файлов через класс-оболочку (которую эта оболочка уже предлагает карты памяти только для чтения, см. github.com/fish2000 /libimread/blob/master/src/); Я буду использовать то, что я узнаю, делая это и из SO, для решения проблемы с общей памятью. - person fish2000   schedule 14.05.2017