Текущий раздел:

Описания RDS

Приложения

Приложение А. Функции, константы и структуры RDS

А.5. Сервисные функции и макросы RDS

А.5.3. Синхронизация потоков RDS

А.5.3.3. rdsLockBlockData – включение блокировки данных

# Приложения

## Приложение А. Функции, константы и структуры RDS

### А.5. Сервисные функции и макросы RDS

#### А.5.3. Синхронизация потоков RDS

##### А.5.3.3. rdsLockBlockData – включение блокировки данных

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

      void RDSCALL rdsLockBlockData(void);

Тип указателя на эту функцию

RDS_VV

Примечания

В RDS одновременно может работать несколько потоков: в режиме расчета, как правило, вместе с главным потоком приложения работает еще и поток расчета. Кроме того, модели блоков могут создавать свои потоки средствами Windows API. Поэтому в RDS, как и в любом многопоточном приложении, имеются средства блокировки данных: нельзя допускать, чтобы разные потоки одновременно обращались к одним и тем же данным в памяти. Поскольку потоки работают параллельно, если один из них начнет запись в какую-либо область памяти, а другой попытается в то же самое время считать данные из этой области или записать туда свои данные, может возникнуть конфликт, который приведет к считыванию неверных данных и другим серьезным ошибкам.

Блокировка данных включается автоматически при вызове функции модели блока или модуля автоматической компиляции, поэтому внутри этих функций о ней можно не задумываться. Если же нужно обратиться к данным блока, модуля автокомпиляции или вызвать сервисную функцию RDS из процедуры немодального окна (которая вызывается Windows в произвольные моменты времени без синхронизации с RDS) или из потока, созданного средствами Windows API, перед обращением необходимо вызвать функцию rdsLockBlockData, а после него – rdsUnlockBlockData.

Функция rdsLockBlockData работает следующим образом:

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

Таким образом, вызвав rdsLockBlockData, программист может быть уверен, что, после того, как она завершится, данные RDS будут в монопольном распоряжении вызвавшего потока. Поскольку функция имеет внутренний счетчик блокировок, ее можно вызывать из одного потока много раз подряд – если данные заблокированы этим же самым потоком, она будет возвращать ему управление немедленно. Такой счетчик позволяет вкладывать вызовы rdsLockBlockData/rdsUnlockBlockData друг в друга: данные будут разблокированы только тогда, когда rdsUnlockBlockData будет вызвана столько же раз, сколько раз была вызвана rdsLockBlockData.

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

Использование функций rdsLockBlockData и rdsUnlockBlockData рассматривается в §1.8 руководства программиста.

См. также

rdsUnlockBlockData, rdsBlockDataSyncCall, rdsUnlockAndCall.