[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Изменение записи - Пример отображения на память и захвата записи

Пример с предыдущей страницы переписан здесь, чтобы использовать
отображение файлов на память. Файл сначала отображается на память с
помощью mmap(2). Каждая запись перед чтением захватывается по
изменению и освобождается после изменения. Программа работает
следующим образом:
   ...    Файл служащих открывается для чтения и записи.

   23-25  Файл служащих отображается на память.

   ...    После входа в цикл for, программа запрашивает у пользователя
          номер записи.

   34-38  Проверка номера записи.

   40-47  Запись захватывается  по изменению.  Это не дает возможности
          другим процессам  тоже захватить  эту запись. fcntl(2) будет
          заблокирована, если  запись уже  захвачена, в  ожидании пока
          все остальные процессы не освободят ее.

   ...    Печатается имя  и  оклад  служащего.  Потом  вводится  новый
          оклад.

   57-59  Захват  по  изменению  записи  снимается  и  она  становится
          доступной для других процессов.

Эта схема захвата записи работает правильно, если используется
допустимое захватывание и все процессы используют эту программу для
изменения файла служащих. Если в файле установлены атрибуты
обязательного захватывания, отображение на память работает следующим
образом. Если запись отображена на память, установка захвата
закончится неудачно (вернет -1). И наоборот, если запись захвачена, ее
отображение на память закончится неудачно. Программа не будет
работать, если файл данных имеет атрибуты обязательного захвата
записи. Так как файл отображается на память в строках 24-25, fcntl(2)
в строке 44 завершится неудачно.
Файл: updatem.c
   ИЗМЕНЕНИЕ ЗАПИСИ - ПРИМЕР ОТОБРАЖЕНИЯ НА ПАМЯТЬ И ЗАХВАТА ЗАПИСИ
 1 #include <sys/mman.h>
 2 #include <stdlib.h>
 3 #include <stdio.h>
 4 #include <fcntl.h>
 5 #include <sys/types.h>
 6 #include <unistd.h>
 7 #include <errno.h>
 8 #include "employee.h"
 9
10 main(int argc, char *argv[])
11 {
12    struct flock lock;
13    off_t size;
14    struct employee *p;
...
23    size = lseek(fd, 0, SEEK_END);
24    p = (struct employee *)mmap(0, size,
25        PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
...
34        position = recnum * sizeof(struct employee);
35        if (position >= size) {
36        printf("record %d not found\n", recnum);
37        continue;
38        }
39
40        lock.l_type = F_WRLCK;        /* lock record */
41        lock.l_whence = SEEK_SET;
42        lock.l_start = position;
43        lock.l_len = sizeof(struct employee);
44        if (fcntl(fd, F_SETLKW, &lock) == -1) {
45         perror(argv[1]);
46         exit(2);
47        }
...
57        lock.l_type = F_UNLCK;        /* release record */
58        fcntl(fd, F_SETLK, &lock);
...
62 }