Есть много способов обеспечить взаимодействие процессов, в этой статье я расскажу об одном из них, об использовании общей памяти.
Функции, которые мы будем использовать:
Аргументы:
KEY - ключ сегмента. Константа IPC_PRIVATE инициирует динамическое выделение ключа.
SIZE - Запрашиваемое число байт для сегмента.
FLAGS - Права доступа к сегменту. Также есть дополнительные флаги: IPC_CREAT - создать, IPC_EXCL - написать что сегмент уже создан.
Аргументы:
ID - идентификатор сегмента.
ADDRESS - адрес, по которому доступен сегмент. В случае NULL выбирается произвольный.
FLAGS - дополнительные флаги.
Аргументы:
ID - идентификатор сегмента.
COMMAND - выполняемая команда, часто это IPC_STAT - получить данные и IPC_RMID - удалить сегмент.
DESC - указатель на структуру, в которую заносятся данные о сегменте. Для IPC_RMID достаточно NULL.
Использование общей памяти
Рассмотрим пример:
owner создаёт общий сегмент с импользование ключа IPC_PRIVATE, заносит туда данные и открывает доступ к нему для всех желающих. user подключается, используя ключ сегмента и читает данные из сегмента.
Вот что получилось:
Система: FreeBSD 8.2
Функции, которые мы будем использовать:
- int shmget(key_t KEY, size_t SIZE, int FLAGS);
Аргументы:
KEY - ключ сегмента. Константа IPC_PRIVATE инициирует динамическое выделение ключа.
SIZE - Запрашиваемое число байт для сегмента.
FLAGS - Права доступа к сегменту. Также есть дополнительные флаги: IPC_CREAT - создать, IPC_EXCL - написать что сегмент уже создан.
- void* shmat(int ID, void* ADDRESS, int FLAGS);
Аргументы:
ID - идентификатор сегмента.
ADDRESS - адрес, по которому доступен сегмент. В случае NULL выбирается произвольный.
FLAGS - дополнительные флаги.
- shmdt(void* ADDRESS);
- int shmctl(int ID, int COMMAND, struct shmid_ds * DESC);
Аргументы:
ID - идентификатор сегмента.
COMMAND - выполняемая команда, часто это IPC_STAT - получить данные и IPC_RMID - удалить сегмент.
DESC - указатель на структуру, в которую заносятся данные о сегменте. Для IPC_RMID достаточно NULL.
Использование общей памяти
Рассмотрим пример:
owner создаёт общий сегмент с импользование ключа IPC_PRIVATE, заносит туда данные и открывает доступ к нему для всех желающих. user подключается, используя ключ сегмента и читает данные из сегмента.
/* Файл owner.c */ #include <stdio.h> #include <string.h> #include <sys/shm.h> #define SHMEM_SIZE 4096 #define SH_MESSAGE "test\n" int main(void) { int shm_id, shm_size; char* shm_buf; struct shmid_ds ds; shm_id = shmget(IPC_PRIVATE, SHMEM_SIZE, IPC_CREAT | IPC_EXCL | 0600); if(shm_id == -1) { fprintf(stderr, "shmget()\n"); return 1; } shm_buf = (char *) shmat(shm_id, NULL, 0); if(shm_buf == (char *) -1) { fprintf(stderr, "shmat()\n"); return 1; } shmctl(shm_id, IPC_STAT, &ds); shm_size = ds.shm_segsz; if(shm_size < strlen(SH_MESSAGE)) { fprintf(stderr, "error\n"); return 1; } strcpy(shm_buf, SH_MESSAGE); printf("ID: %d\n", shm_id); printf("Enter"); fgetc(stdin); shmdt(shm_buf); shmctl(shm_id, IPC_RMID, NULL); return 0; }
/* Файл user.c */ #include <sys/shm.h> #include <stdio.h> int main(int argc, char ** argv) { int shm_id; char* shm_buf; if(argc < 2) { fprintf(stderr, "error(argc)\n"); return 1; } shm_id = atoi(argv[1]); shm_buf = (char *) shmat(shm_id, 0, 0); if(shm_buf == (char*) -1) { fprintf(stderr, "shmat()\n"); return 1; } printf("%s\n", shm_buf); shmdt(shm_buf); return 0; }
Вот что получилось:
Использование общей памяти - owner |
Использование общей памяти - user |
Система: FreeBSD 8.2
Комментариев нет:
Отправить комментарий