/* Программа 2 (06-3b.c) для иллюстрации
некорректной работы с разделяемой памятью */
/* Мы организуем разделяемую память для массива из трех
целых чисел. Первый элемент массива является счетчиком
числа запусков программы 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);
}
/* Пытаемся эксклюзивно создать разделяемую память для
сгенерированного ключа, т.е. если для этого ключа она
уже существует, системный вызов вернет отрицательное
значение. Размер памяти определяем как размер массива
из трех целых переменных, права доступа 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");