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