[<<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 }