Исключение из этого правила возникает, если выражение shmflg & SHM_RDONLY
true. В этом случае в совместно используемую память нельзя писать, даже если права доступа предоставляют такую возможность.Функция shmdt
shmat. В случае успеха функция вернет 0, в случае ошибки - -1. Имейте в виду, что отсоединение совместно используемой памяти не уничтожает ее, а только делает эту память недоступной для текущего процесса.Функции управления совместно используемой памятью (к счастью) гораздо проще аналогичных, но более сложных функций для семафоров:
int shmctl(int shm_id, int command, struct shmid_ds *buf);
У структуры типа shmid_ds
struct shmid_ds {
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
}
Первый параметр shm_id
shmget.Второй параметр command
| Значение | Описание |
|---|---|
IPC_STAT | Задаёт данные в структуре shmid_ds, отображающие значения, связанные с совместно используемой памятью |
IPC_SET | Устанавливает значения, связанные с совместно используемой памятью в соответствии с данными из структуры типа shmid_ds, если у процесса есть право на это действие |
IPC_RMID | Удаляет сегмент совместно используемой памяти |
Третий параметр buf
В случае успеха возвращает 0, в случае ошибки — -1. В стандарте X/Open не описано, что произойдет, если вы попытаетесь удалить присоединенный к процессу сегмент совместно используемой памяти. Обычно присоединенный, но удаленный сегмент совместно используемой памяти продолжает функционировать до тех пор, пока не будет отсоединен от последнего процесса. Но поскольку это поведение не задано в стандарте, на него лучше не рассчитывать.
Выполните упражнение 14.2.
После знакомства с функциями совместно используемой памяти можно написать программу для их использования. В данном упражнении вы напишите пару программ: shm1.c и shm2.c. Первая (потребитель) создаст сегмент разделяемой памяти и затем отобразит любые данные, записанные в него. Вторая (поставщик) присоединит существующий сегмент совместно используемой памяти и позволит вам ввести данные в этот сегмент.
1. Сначала создайте общий заголовочный файл для описания совместно используемой памяти, которую вы хотите предоставить. Назовите его shm_com.h.
#define TEXT_SZ 2048
struct shared_use_st {
int written_by_you;
char some_text[TEXT_SZ];
};
В файле определена структура, которая будет применяться в обеих программах: потребителе и поставщике. Вы используете флаг written_by_you
int для того, чтобы сообщить потребителю о том, что данные записаны в оставшуюся часть структуры, и произвольно решаете, что необходимо передать до 2 Кбайт текста.2. Первая программа shm1.c — потребитель. После заголовочных файлов создается сегмент совместно используемой памяти (размер равен вашей структуре, описывающей совместно используемую память) с помощью вызова shmget
IPC_CREAT.#include
#include
#include
#include
#include
#include "shm_com.h"
int main() {
int running = 1;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
int shmid;
srand((unsigned int)getpid());
shmid = shmget((key_t)1234, sizeof(struct shared_use_st),
0666 | IPC_CREAT);
if (shmid == -1) {
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}
3. Теперь вы делаете совместно используемую память доступной программе.
shared_memory = shmat(shmid, (void *)0, 0);
if (shared memory == (void *)-1) {
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}