[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Изменение записи - Пример

В этом примере изменяется запись о служащем. Перед чтением запись
захватывается по изменению и освобождается после изменения. Программа
работает следующим образом:
   ...    Файл служащих открывается для чтения и записи. После входа в
          цикл for, программа просит пользователя ввести номер записи.

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

   38-44  Текущая  позиция   файла  устанавливается  на  захватываемую
          запись. Затем запись читается.
          Замечание:  lseek(2)  используется  явно,  чтобы  установить
          текущую позицию  в файле. Использование fcntl(2) для захвата
          записи не приводит к изменению текущей позиции файла.

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

   51-52  lseek(2) используется  снова, чтобы установить позицию файла
          на захваченную запись. Измененная запись пишется в файл.

   54-55  Захват по  изменению снимается, чтобы все остальные процессы
          могли использовать измененную запись.

Эта схема захвата записи работает правильно, если все процессы
используют эту программу для изменения файла служащих. Этого  можно
достигнуть соответствующей установкой прав доступа файла служащих и
бита "установки идентификатора пользователя" этой программы. Кроме
того, обеспечение такого доступа к файлу служащих делает программу
уверенной в том, что запись доступна в каждый момент только одному
процессу.
Файл: update1.c
                      ИЗМЕНЕНИЕ ЗАПИСИ - ПРИМЕР
                      ЗАХВАТ ЗАПИСИ ПО ИЗМЕНЕНИЮ
 1 #include <sys/types.h>
 2 #include <stdio.h>
 3 #include <unistd.h>
 4 #include <fcntl.h>
 5 #include <stdlib.h>
 6 #include <errno.h>
 7 #include "employee.h"
 8
 9 main(int argc, char *argv[])
10 {
11      struct flock lock;
...
28       position = (recnum-1) * sizeof(record);
29       lock.l_type = F_WRLCK;        /* lock record */
30       lock.l_whence = SEEK_SET;
31       lock.l_start = position;
32       lock.l_len = sizeof(record);
33       if (fcntl(fd, F_SETLKW, &lock) == -1) {
34            perror(argv[1]);
35            exit(2);
36       }
37
38       lseek(fd, position, SEEK_SET);      /* read record */
39       if (read(fd, &record, sizeof(record)) == 0) {
40            printf("record %d not found\n", recnum);
41            lock.l_type = F_UNLCK;
42            fcntl(fd, F_SETLK, &lock);
43            continue;
44       }
...
51       lseek(fd, position, SEEK_SET);
52       write(fd, &record, sizeof(record));
53
54       lock.l_type = F_UNLCK;        /* release record */
55       fcntl(fd, F_SETLK, &lock);
...
58 }