[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Выдача информации о захватах записи - Пример

Так как несколько человек могут изменять различные записи в файле,
может быть необходимо выдать отчет о захваченных записях. Например,
полезно знать, что какие-то записи в файле захватываются слишком часто
в одной и той же программе. Тогда эту программу можно исправить.
Программа, приведенная на следующей странице, печатает список всех
захваченных записей, тип захвата и идентификатор процесса,
захватившего запись. Программа проанализирует на захват все записи в
файле. Для этого используется системный вызов fcntl(2) с запросом
F_GETLK, тип захвата должен быть равен F_WRLCK, независимо от типа
захвата записи. Эта программа работает следующим образом:
   12     Описание структуры захвата.

   ...    Файл открывается  для  чтения  и  определяется  его  размер.
          Размер файла возвращает lseek(2).

   22     Записи проверяются с начала файла.

   25-26  Этот цикл for проверяет каждую запись в файле.

   27-30  Тип захвата  запроса -  это захват по изменению, но fcntl(2)
          вызывается для  всех записей  и  при  вызове  изменяет  поле
          l_type на  тип захвата проверяемой записи. Поле длины записи
          (l_len) и  ее начальная  позиция (l_start)  также могут быть
          изменены. Именно поэтому l_start используется как переменная
          цикла в  операторе for.  Если запись,  задаваемая l_start  и
          l_len, свободна, цикл продолжается со следующей записи.

   32-33  Печатается тип захвата.

   34-35  Печатается номер  записи. Заметим,  что все  записи одного и
          того же размера.

   36-39  Если конец  файла, начиная  с l_start,  захвачен,  то  l_len
          станет равным  нулю. Тогда  вычисляется число  оставшихся  в
          файле записей.

   40-41  Печатается число захваченных записей.

Помните, что l_start и l_len могут измениться при вызове fcntl(2) с
F_GETLK. Это происходит, когда расположение существующего захвата
превышает или не точно соответствует значениям, переданным fcntl(2) в
структуре захвата. Эта программа работает следующим образом:
$ getlocks data
File: data
Pid: 14585      Write lock      Record number: 1        Number of
records: 1
Pid: 14605      Read lock       Record number: 3        Number of
records: 1

Файл: getlocks.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 employee record;
12     struct flock lock;
13     off_t size;
...
22     lock.l_whence = SEEK_SET;
23     lock.l_len = sizeof(record);
24     printf("File: %s\n", argv[1]);
25     for (lock.l_start = 0; lock.l_start < size;
26      lock.l_start += lock.l_len) {
27      lock.l_type = F_WRLCK;
28      fcntl(fd, F_GETLK, &lock);
29      if (lock.l_type == F_UNLCK)     /* not locked */
30          continue;
31      printf("Pid: %ld", lock.l_pid);
32      printf("\t%s lock",
33          (lock.l_type == F_WRLCK)? "Write" : "Read");
34      printf("\tRecord number: %ld",
35          lock.l_start/sizeof(record));
36      if (lock.l_len == 0) {     /* rest of file */
37          lock.l_len = size - lock.l_start;
38          lock.l_start = size;  /* terminate for loop */
39          }
40      printf("\tNumber of records: %ld\n",
41          lock.l_len/sizeof(record));
42     }
43 }