Открыть объект в разделяемой области памяти
#include <fcntl.h>#include <sys/mman.h>int shm_open( const char *name,int oflag,mode_t mode );
<fcntl.h>
): O_EXCL
ниже. В противном случае создается объект в разделяемой области памяти и его права устанавливаются в соответствии со значением mode и маской создания режима файла для процесса. O_EXCL
и O_CREAT
, то shm_open() завершится с ошибкой, если объект разделяемой памяти существует. Операции проверки его существования и создание объекта, если такового не существует, являются атомарными по отношению к другим процессам, выполняющим shm_open(), открывая тот же объект в разделяемой памяти с помощью комбинации битов O_EXCL
и O_CREAT
. O_RDWR
, размер объекта урезается до нулевой длины, но режим доступа и владелец не изменяются. libc
Функция shm_open() возвращает файловый дескриптор, связанный с объектом в разделяемой области памяти, указанным в name. Этот файловый дескриптор используется другими функциями для обращения к объекту в разделяемой области памяти (например, mmap(), mprotect()). Флаг файлового дескриптора FD_CLOEXEC в fcntl() устанавливается для данного файлового дескриптора.
Аргумент name интерпретируется следующим образом:
name | Новая запись в ространстве имен |
---|---|
entry | CWD/entry |
/entry | /dev/shmem/entry |
entry/newentry | CWD/entry/newentry |
/entry/newentry | /entry/newentry |
где CWD
- это текущий рабочий каталог программы в момент, когда она вызвала shm_open().
Состояние объекта в разделяемой памяти, включая все связанные с ним данные, сохраняется до тех пор, пока объект в разделяемой области памяти не будет удален и оставшиеся ссылки на него во всех процессах не исчезнут.
Неотрицательное целое число, представляющее неиспользуемый файловый дескриптор с минимальным номером. Если возникла ошибка функция возвращается -1
, а код ошибки записывается в errno.
O_TRUNC
и разрешение на запись отклонено. O_CREAT
и O_EXCL
установлены, а указанный объект в разделяемой области памяти уже существует. NAME_MAX
. O_CREAT
не установлен и именованный объект в разделяемой области памяти не существует; O_CREAT
установлен, и либо префикс имени не существует, либо аргумент name указывает на пустую строку. В данном примере создается объект в разделяемой области памяти, но работы с ним не производится:
#include <stdio.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <limits.h>#include <sys/mman.h>int main( int argc, char** argv ){int fd;unsigned *addr;/* In case the unlink code isn't executed at the end */if ( argc != 1 ){shm_unlink( "/bolts" );return (EXIT_SUCCESS);}/* Create a new memory object */fd = shm_open( "/bolts", O_RDWR | O_CREAT, 0777 );if ( fd == -1 ){fprintf( stderr, "Open failed:%s\n", strerror( errno ) );return (EXIT_FAILURE);}/* Set the memory object's size */if ( ftruncate( fd, sizeof( *addr ) ) == -1 ){fprintf( stderr, "ftruncate: %s\n", strerror( errno ) );return (EXIT_FAILURE);}/* Map the memory object */addr = mmap( 0, sizeof( *addr ), PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0 );if ( addr == MAP_FAILED ){fprintf( stderr, "mmap failed: %s\n", strerror( errno ) );return (EXIT_FAILURE);}printf( "Map addr is 0x%08x\n", addr );/* Write to shared memory */*addr = 1;/** The memory object remains in* the system after the close*/close( fd );/** To remove a memory object* you must unlink it like a file.** This may be done by another process.*/shm_unlink( "/bolts" );return (EXIT_SUCCESS);}
В данном примере используется объект в разделяемой области памяти для обмена данными с порожденным новым процессом:
#include <stdio.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <sys/mman.h>main(int argc, char * argv[]){int fd;unsigned *addr;/* In case the unlink code isn't executed at the end */if ( argc != 1 ){shm_unlink( "/bolts" );return (EXIT_SUCCESS);}/* Create a new memory object */fd = shm_open( "/bolts", O_RDWR | O_CREAT, 0777 );if ( fd == -1 ){fprintf( stderr, "Open failed : %s\n", strerror( errno ) );return (EXIT_FAILURE);}/* Set the memory object's size */if ( ftruncate( fd, sizeof( *addr ) ) == -1 ){fprintf( stderr, "ftruncate : %s\n", strerror( errno ) );return (EXIT_FAILURE);}/* Map the memory object */addr = mmap( 0, sizeof( *addr ), PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0 );if ( addr == MAP_FAILED ){fprintf( stderr, "mmap failed:%s\n", strerror( errno ) );return (EXIT_FAILURE);}printf( "Map addr is %6.6X\n", addr );printf( "Press break to stop.\n" );sleep( 3 ); /* So you can read above message *//* We unlink so object goes away on last close. */shm_unlink( "/bolts" );*addr = '0';if ( fork() ){for ( ; ; )if ( *addr == '0' )putc( *addr = '1', stderr );elsesched_yield();} else {for ( ; ; )if ( *addr == '1' )putc( *addr = '0', stderr );elsesched_yield();}return (EXIT_SUCCESS);}
POSIX 1003.1 Shared Memory Objects
struct stat, fcntl(), ftruncate(), mmap(), munmap(), mprotect(), open(), shm_ctl(), shm_ctl_special(), shm_unlink(), sysconf()
Предыдущий раздел: Описание API системной библиотеки