Локальные сети персональных компьютеров. Работа с сервером Novell NetWare

Блокирование логических записей


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

Средства сетевой оболочки позволяют создавать группы логических записей и блокировать их все вместе, по аналогии с группами блокируемых файлов и физических записей.

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

Выполнив блокировку логических записей, программа выполняет все необходимые действия с файлами и затем разблокирует логические записи, предоставляя доступ к данным другим процессам.

Необходимо отметить, что при синхронизации процессов с помощью логических записей (а также семафоров, которые мы рассмотрим ниже) программы сами должны проверять состояние записей и правильно выполнять доступ к файлам, так как физически данные в файлах не блокируются.

Набор функций, используемый для работы с логическими записями, аналогичен набору функций для работы с физическими записями. Однако в отличие от физических записей, которые связаны с файлами и идентифицируются индексом файла, смещением и размером, логические записи идентифицируются по имени.

Для создания группы логических записей используется функция LogLogicalRecord().
Удалить запись из группы можно функцией ClearLogicalRecord(). Вся группа записей удаляется функцией ClearLogicalRecordSet().

Записи можно блокировать сразу при их добавлении в группу либо можно заблокировать сразу все записи, относящиеся к группе, вызвав функцию LockLogicalRecordSet().

Для разблокирования логической записи используется функция ReleaseLogicalRecord(). Если надо разблокировать сразу все логические записи, вызывайте функцию ReleaseLogicalRecordSet().

Функция LogLogicalRecord() имеет следующий прототип:

int LogLogicalRecord(char LogicalRecordName, BYTE LockDirective,WORD Timeout);



Параметр LogicalRecordName задает имя логической записи, добавляемой в группу блокируемых записей. Имя может иметь длину до 100 байт и должно быть в формате текстовой строки, закрытой двоичным нулем.

Параметр LockDirective определяет, надо ли блокировать запись сразу после ее добавления в группу:

0x00 Запись добавляется в группу, но не блокируется
0x01 Добавляемая запись блокируется для использования заблокировавшей его программой в монопольном режиме
0x03 Добавляемая запись блокируется для совместного использования
Параметр Timeout определяет период времени (в 18-x долях секунды), в течение которого файл-сервер будет ожидать, если запись нельзя заблокировать немедленно. Если для этого параметра задать нулевое значение, ожидание выполняться не будет.

Функция возвращает 0 при успешном завершении или код ошибки:

Код ошибки Значение
0x96 Мало памяти на файл-сервере
0xFE Истек период ожидания, заданный параметром Timeout, но запись так и не удалось заблокировать
0xFF Сбой при блокировании записи
Для удаления записи из группы можно использовать функцию ClearLogicalRecord():

int ClearLogicalRecord(char LogicalRecordName);

Параметр этой функции задает имя логической записи, удаляемой из группы. Функция возвращает нулевое значение или значение 0xFF, если в группе нет указанной записи.

Функция ClearLogicalRecordSet() позволяет разблокировать все записи группы и удалить группу:



void ClearLogicalRecordSet(void);

Прототип функции LockLogicalRecordSet(), используемой для блокирования группы записей:

int LockLogicalRecordSet(WORD Timeout);

Параметр Timeout используется так же, как и при вызове функции LogLogicalRecord().

Функция возвращает 0 при успешном завершении или код ошибки:

Код ошибки Значение
0xFE Истек период ожидания, заданный параметром Timeout, но запись так и не удалось заблокировать
0xFF Сбой при блокировании записи
После того как группа записей заблокирована, вы можете разблокировать отдельные записи или всю группу сразу.

Для разблокирования отдельных записей используйте функцию ReleaseLogicalRecord():

int ReleaseLogicalRecord(char LogicalRecordName);

Параметр задает имя записи. Функция возвращает нулевое значение или значение 0xFF, если указанной записи нет в группе.

Если надо разблокировать сразу все записи, добавленные в группу, используйте функцию ReleaseLogicalRecordSet():

void ReleaseLogicalRecordSet(void);

Для добавления записей в группу вместо функции LogLogicalRecord() можно использовать функцию D0h прерывания INT21h:

На входе: AH = D0h;
AL = Параметр LockDirective;
BP = Параметр Timeout;
DS:DX = Адрес имени логической записи.
На выходе: AL = Код ошибки или 0, если операция завершилась без ошибок.
Для удаления записи из списка вместо функции ClearLogicalRecord() можно использовать функцию D4h прерывания INT 21h:

На входе: AH = D4h;
DS:DX = Адрес имени логической записи.
На выходе: AL = Код ошибки или 0, если операция завершилась без ошибок.
Для удаления группы записей и разблокирования всех записей вместо функции ClearLogicalRecordSet() можно использовать функцию D5h прерывания INT 21h:

На входе: AH = D5h.
На выходе: AL = Код ошибки или 0, если операция завершилась без ошибок.
Для блокирования группы записей вместо функции LockLogicalRecordSet() можно использовать функцию D1h прерывания INT 21h:

На входе: AH = D1h;
AL = Регистр должен содержать значение 0;
BP = Параметр Timeout.
На выходе: AL = Код ошибки или 0, если операция завершилась без ошибок.
<


Для разблокирования записи вместо функции ReleaseLogicalRecord() можно использовать функцию D2h прерывания INT 21h:

На входе: AH = D2h;
DS:DX = Адрес имени логической записи;
На выходе: AL = Код ошибки или 0, если операция завершилась без ошибок.
Для разблокирования группы записей вместо функции ReleaseLogicalRecordSet() можно использовать функцию D3h прерывания INT 21h:

На входе: AH = D3h.
На выходе: Регистры не используются.

Содержание раздела