Зачем использовать shm_open?

В чем преимущество: shm_open следует за mmap?
Почему бы не создать обычный файл, а затем передать этот fd в mmap?
Я не вижу преимущества shm_open — это просто ссылки, они не?

Я читал человека всей семьи. Мне кажется, что секрет в действии mmaping - тип файла кажется бессмысленным.

Любые указатели будут хороши, особенно с учетом производительности.
Мой контекст представляет собой (циклически перезаписываемый) буфер (скажем, 128 МБ), который будет постоянно записываться одним процессом и постоянно выгружаться другим.

В качестве примера: что не так с этим подходом open/mmap.

ИЗМЕНИТЬ
Если быть точным, то одно из следующего лучше другого:

fd = open("/dev/shm/myshm.file", O_CREAT|O_RDWR, S_IRUSR | S_IWUSR);
mem = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

vs.

fd = shm_open("/myshm.file", O_RDWR|O_CREATE, S_IRUSR | S_IWUSR);
mem = mmap(...same as before...);

Когда я создал файл с обычным open под /dev/shm фс и свалил в него Гиг мусора, моя доступная память уменьшилась на 1Г, а доступное место на диске осталось прежним.
В чем разница между двумя способами ?


person Trevor    schedule 21.07.2014    source источник
comment
Просто попробуйте. запись в файл может быть в сто раз медленнее.   -  person Jens Gustedt    schedule 22.07.2014


Ответы (3)


Если вы откроете и mmap() обычный файл, данные окажутся в этом файле.

Если вам просто нужно разделить область памяти без необходимости сохранять данные, что влечет за собой дополнительные накладные расходы на ввод-вывод, используйте shm_open().

Такая область памяти также позволит вам хранить другие типы объектов, такие как мьютексы или семафоры, которые вы не можете хранить в обычном файле с mmap() на большинстве систем.

person nos    schedule 21.07.2014
comment
Но что, если я создал файл в /dev/shm fs? вот так, открыть(/dev/shm/myshm,w)? В чем преимущество использования shm_open? - person Trevor; 22.07.2014
comment
Тогда это будет почти то же самое, если вы используете shm_open или open, но просто помните, что это специфично для Linux. Было бы довольно бесполезно делать, когда существует стандартный подход. shm_open также позаботится о местонахождении /dev/shm, если он смонтирован в нестандартном месте. - person nos; 23.07.2014
comment
Спасибо за указание на проблему переносимости. Наш продукт поставляется клиентам как виртуальная машина, поэтому мы контролируем распространение нашего кода, чтобы мы могли им управлять. В первую очередь меня привлекла невозможность создавать логические каталоги в /dev/shm fs. Это артефакт shm_open glibc и не проблема fs, поэтому я использую open(). - person Trevor; 23.07.2014
comment
@Trevor, обратите внимание, что в соответствии со стандартом POSIX: Интерпретация символов косой черты, отличных от начального символа косой черты в имени, определяется реализацией. Почему бы не придерживаться стандартного вызова API и просто обойти его? ограничения, напр. с помощью символа подчеркивания или другого специального символа в имени файла для разделения логических частей вместо создания каталогов под /dev/shm? - person Hristo Iliev; 23.07.2014
comment
То, что вы предлагаете, действительно правильно, и я все еще считаю это. Однако, например, если я захочу выполнить inotify в нашем каталоге в /dev/shm, мне придется прибегнуть к выполнению inotify в /dev/shm — и быть подверженным другим процессам, регистрирующимся в этом пространстве. Просто один пример, который приходит на ум - person Trevor; 23.07.2014
comment
@nos, может ли shm_open, за которым следует mmap, позволить вам сохранить mutex_t pthread, который можно изменить с помощью функции pthread_mutexattr_setpshared в Ubuntu Linux 15.10 glibc 2.21? Причина этого вопроса в том, что я хотел бы использовать pthread_mutex_t для настройки межпроцессной синхронизации. Спасибо. - person Frank; 22.04.2016
comment
@Христо Илиев и Тревор, может ли shm_open, за которым следует mmap, позволить вам сохранить mutex_t pthread, который можно изменить с помощью функции pthread_mutexattr_setpshared в Ubuntu Linux 15.10 glibc 2.21? Причина этого вопроса в том, что я хотел бы использовать pthread_mutex_t для настройки межпроцессной синхронизации. Спасибо - person Frank; 22.04.2016
comment
@ Фрэнк, да, ты можешь это сделать. - person nos; 22.04.2016
comment
@nos, спасибо за ответ. Не могли бы вы взглянуть на вывод различий UNIX для glibc 2.21 и glibc 2.22 для pthread_mutexattr_setpshared.c, показанный в fossies.org/diffs/glibc/2.21_vs_2.22/nptl/ и объяснить, почему я все еще могу использовать функцию pthread_mutexattr_setpshared.c в Ubuntu Linux 15.10 glibc 2.21 для настройте pthread_mutex_t для межпроцессной синхронизации. Мне сказали, возможно, неправильно, что в функции pthread_mutexattr_setpshared.c в Ubuntu Linux 15.10 glibc 2.21 есть ошибка. Спасибо. - person Frank; 22.04.2016

Оба вызова практически эквивалентны в современном Linux — первый подход можно использовать для доступа к разделяемой памяти POSIX из таких языков, как go (см. https://github.com/fabiokung/shm/blob/master/shm_linux.go), где общая память POSIX изначально недоступна - она ​​может отличаться для другой ОС/версии, где 1st вызов приведет к созданию какого-либо файла или /dev/shm просто недоступен и/или, возможно, к снижению производительности. Правила объединения путей также могут меняться от версии к версии librt.

1-й подход, называемый API файлов с отображением памяти (поддерживается в стандартных библиотеках)

2-й называется API общей памяти POSIX (требуется librt aka libposix в Linux в качестве зависимости. Он внутренне создает путь и вызывает open)

person Maxim Sinev    schedule 30.03.2017

Прочитав источник shm_open, я могу сказать, что эти два метода почти одинаковы.

ссылка: https://code.woboq.org/userspace/glibc/sysdeps/posix/shm_open.c.html

shm_open просто добавляет префикс shm_dir, затем вызывает обычный системный вызов open, ничего особенного.

person LeeLee    schedule 08.12.2020