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

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

   28-36  Запись захватывается  по чтению. Процесс подвешивается, если
          запись уже захвачена по изменению.

   ...    Если попытка прочитать запись неуспешна, то захват по чтению
          снимается и программа идет на начало цикла. Иначе печатается
          имя служащего и его оклад.

   50-54  Если пользователь не хочет изменять запись, захват по чтению
          снимается и программа продолжается с начала цикла.
          Предупреждение:  Не   забудьте   освободить   запись   перед
          переходом на начало цикла.

   55-59  Захват по чтению переводится в захват по изменению. fcntl(2)
          блокируется, если  есть  другие  процессы,  захватившие  эту
          запись по  чтению. После того как все процессы освободят эту
          запись, наш  процесс просыпается  и захватывает  запись. Для
          предотвращения взаимной  блокировки, любой  другой  процесс,
          пытающийся перевести  свой захват  этой записи  по чтению  в
          захват по изменению, закончится неуспешно.

   ...    Запись о служащем изменяется.

   66-67  Захват по изменению  снимается с записи.

Файл: update2.c
                      ИЗМЕНЕНИЕ ЗАПИСИ - ПРИМЕР
                 ЗАХВАТ ЗАПИСИ ПО ЧТЕНИЮ И ИЗМЕНЕНИЮ
 1 #include <sys/types.h>
 2 #include <stdlib.h>
 3 #include <stdio.h>
 4 #include <fcntl.h>
 5 #include <unistd.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_RDLCK;          /* read lock */
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       }
...
50       if (ans[0] != 'y') {
51            lock.l_type = F_UNLCK;
52            fcntl(fd, F_SETLK, &lock);
53            continue;
54       }
55       lock.l_type = F_WRLCK;          /* write lock */
56       if (fcntl(fd, F_SETLKW, &lock) == -1) {
57            perror(argv[1]);
58            exit(3);
59       }
...
66       lock.l_type = F_UNLCK; /* release record */
67       fcntl(fd, F_SETLK, &lock);
...
70 }