Руководство программиста для Linux


Разделяемая память - часть 4


Вызов очень похож на msgctl(), выполняющий подобные задачи для очередей сообщений. Поэтому мы не будем слишком детально его обсуждать. Употребляемые значения команд следующие:

IPC_STAT

Берет структуру shmid_ds для сегмента и сохрает ее по адресу, указанному buf-ом.

IPC_SET

Устанавливает значение ipc_perm-элемента структуры shmid_ds. Сами величины берет из аргумента buf.

IPC_RMID

Помечает сегмент для удаления.

IPC_RMID в действительности не удаляет сегмент из ядра, а только помечает для удаления. Настоящее же удаление не происходит, пока последний процесс, привязанный к сегменту, не "отвяжется" от него как следует. Конечно, если ни один процесс не привязан к сегменту на данный момент, удаление осуществляется немедленно.

Снятие привязки производит системный вызов shmdt. Системный вызов shmdt() SYSTEM SALL: shmdt(); PROTOTYPE: int shmdt ( char *shmaddr ); RETURNS: -1 в случае ошибки: errno = EINVAL (ошибочно указан адрес привязки)

После того, как разделяемый сегмент памяти больше не нужен процессу, он должен быть отсоединен вызовом shmdt(). Как уже отмечалось, это не то же самое, что удаление сегмента из ядра. После успешного отсоединения значение элемента shm_nattch структуры shmid_ds уменьшается на 1. Когда оно достигает 0, ядро физически удаляет сегмент.

shmtool: Интерактивный обработчик разделяемых сегментов памяти

Описание

Наш последний пример объектов System V IPC - это shmtool: средство командной строки для создания, чтения, записи и удаления разделяемых сегментов памяти. Так же, как и в предыдущий примерах, во время исполнения любой операции сегмент создается, если его прежде не было.

Синтаксис командной строки

Запись строк в сегмент

shmtool w "text"

Получение строк из сегмента

shmtool r

Изменение прав доступа (mode)

shmtool m (mode)

Удаление сегмента

shmtool d

Примеры

shmtool w test

shmtool w "This is a test"

shmtool r

shmtool d

shmtool m 660

Код #include #include #include #include #define SEGSIZE 100main(int argc, char *argv[]) { key_t key; int shmid, cntr; char *segptr; if(argc == 1) usage(); /* Создаем особый ключ через вызов ftok() */ key = ftok(".", 'S'); /* Открываем разделяемый сегмкнт памяти - если нужно, создаем */ if((shmid = shmget(key, SEGSIZE, IPC_CREAT|IPC_EXCL|0660)) == -1) { printf("Shared memory segment exists - opening as a client\n"); /* Скорее всего, сегмент уже существует - попробуем как клиент */ if((shmid = shmget(key, SEGSIZE, 0)) == -1) { perror("shmget"); exit(1); } } else { printf("Creating new shared memory segment\n"); } /* Привязывем (распределяем) разделяемый сегмент памяти в текущем процессе */ if((segptr = shmat(shmid, 0, 0)) == -1) { perror("shmat"); exit(1); } switch(tolower(argv[1][0])) { case 'w': writeshm(shmid, segptr, argv[2]); break; case 'r': readshm(shmid, segptr); break; case 'd': removeshm(shmid); break; case 'm': changemode(shmid, argv[2]); break; default: usage(); } } writeshm(int shmid, char *segptr, char *text) { strcpy(segptr, text); printf("Done...\n"); } readshm(int shmid, char *segptr) { printf("segptr: %\n", segptr); } removeshm(int shmid) { shmctl(shmid, IPC_RMID, 0); printf("Shared memory segment marked for deletion\n"); } changemode(int shmid, char *mode) { struct shmid_ds myshmds; /* Копируем текущее значение для внутренней структуры данных в myshmds */ shmctl(shmid, IPC_STAT, &myshmds); /* Выводим на экран старые права доступа */ printf("Old permissions were: %o\n", myshmds.shm_perm.mode); /* Исправляем значение режима доступа в копии */ sscanf(mode, "%o", &myshmds.shm_perm.mode); /* Обновляем действующее значение режима доступа */ shmctl(shmid, IPC_SET, &myshmds); printf("New permissions are: %o\n", myshmds.shm_perm.mode); } usage() { fprintf(stderr, "shmtool - A utility for tinkering with shared memory\n"); fprintf(stderr, "\nUSAGE: shmtool (w)rite \n"); fprintf(stderr, " (r)ead\n"); fprintf(stderr, " (d)elete\n"); exit(1); fprintf(stderr, " (m)ode change \n"); exit(1); }

| |

 




Начало  Назад  Вперед



Книжный магазин