/* Программа 1 (06-3а.с) для иллюстрации
некорректной работы с разделяемой памятью */
/* Мы организуем разделяемую память для массива из трех целых
чисел. Первый элемент массива является счетчиком числа
запусков программы 1, т. е. данной программы, второй элемент
массива – счетчиком числа запусков программы 2, третий
элемент массива – счетчиком числа запусков обеих программ */
#include
#include
#include
#include
#include
int main()
{
int *array; /* Указатель на разделяемую память */
int shmid; /* IPC дескриптор для области
разделяемой памяти */
int new = 1; /* Флаг необходимости инициализации
элементов массива */
char pathname[] = "06-3a.c"; /* Имя файла,
использующееся для генерации ключа. Файл с таким
именем должен существовать в текущей директории */
key_t key; /* IPC ключ */
long i;
/* Генерируем IPC ключ из имени файла 06-3a.c в
текущей директории и номера экземпляра области
разделяемой памяти 0 */
if((key = ftok(pathname,0)) < 0){
printf("Can\'t generate key\n");
exit(-1);
}
/* Пытаемся эксклюзивно создать разделяемую память для
сгенерированного ключа, т.е. если для этого ключа она
уже существует, системный вызов вернет отрицательное
значение. Размер памяти определяем как размер массива
из 3-х целых переменных, права доступа 0666 – чтение и
запись разрешены для всех */
if((shmid = shmget(key, 3*sizeof(int),
0666|IPC_CREAT|IPC_EXCL)) < 0){
/* В случае возникновения ошибки пытаемся определить:
возникла ли она из-за того, что сегмент разделяемой
памяти уже существует или по другой причине */
if(errno != EEXIST){
/* Если по другой причине – прекращаем работу */
printf("Can\'t create shared memory\n");
exit(-1);
} else {
/* Если из-за того, что разделяемая память уже
существует – пытаемся получить ее IPC дескриптор
и, в случае удачи, сбрасываем флаг необходимости
инициализации элементов массива */
if((shmid = shmget(key, 3*sizeof(int), 0)) < 0){
printf("Can\'t find shared memory\n");