Основы операционных систем. Практикум



         

Example.6.3a


/* Программа 1 (06-3а.с) для иллюстрации некорректной работы с разделяемой памятью */ /* Мы организуем разделяемую память для массива из трех целых чисел. Первый элемент массива является счетчиком числа запусков программы 1, т. е. данной программы, второй элемент массива – счетчиком числа запусков программы 2, третий элемент массива – счетчиком числа запусков обеих программ */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <errno.h> 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"); exit(-1); } new = 0; } } /* Пытаемся отобразить разделяемую память в адресное пространство текущего процесса. Обратите внимание на то, что для правильного сравнения мы явно преобразовываем значение -1 к указателю на целое.*/ if((array = (int *)shmat(shmid, NULL, 0)) == (int *)(-1)){ printf("Can't attach shared memory\n"); exit(-1); } /* В зависимости от значения флага new либо инициализируем массив, либо увеличиваем соответствующие счетчики */ if(new){ array[0] = 1; array[1] = 0; array[2] = 1; } else { array[0] += 1; for(i=0; i<1000000000L; i++); /* Предельное значение для i может меняться в зависимости от производительности компьютера */ array[2] += 1; } /* Печатаем новые значения счетчиков, удаляем разделяемую память из адресного пространства текущего процесса и з авершаем работу */ printf("Program 1 was spawn %d times, program 2 - %d times, total - %d times\n", array[0], array[1], array[2]); if(shmdt(array) < 0){ printf("Can't detach shared memory\n"); exit(-1); } return 0; }

Листинг 6.3a. Программа 1 (06-3а.с) для иллюстрации некорректной работы с разделяемой памятью.

Закрыть окно






Содержание  Назад  Вперед