[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]

Программирование: Разработка и отладка программ


Службы блокировки с поддержкой многопроцессорных систем

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

В этих целях AIX предоставляет набор элементарных служб блокировки, на основе которых могут быть созданы службы блокировки более высокого уровня. Для создания служб блокировки с поддержкой многопроцессорных систем (таких как стандартные взаимные блокировки) программисты должны применять элементарные службы блокировки, описанные в этом разделе, а не элементарные операции, такие как compare_and_swap.

Службы блокировки с поддержкой многопроцессорных систем

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

Службы блокировки применяют слово блокировки для обозначения состояния блокировки: 0 (ноль) обозначает свободный ресурс, а 1 (один) - занятый. Таким образом, при выполнении блокировки объекта служба должны выполнить следующие действия:

определить значение слова блокировки
если ресурс свободен
        установить состояние "занято"
        вернуть состояние успешного выполнения (SUCCESS)
... 

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

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

_check_lock Обеспечивает атомарную проверку и изменение переменной размером в одно слово с использованием ограничения на импорт в многопроцессорных системах. Процедура compare_and_swap выполняет аналогичные действия, но не использует ограничение на импорт, и поэтому недопустима в службе блокировки.
_clear_lock Обеспечивает атомарное изменение переменной размером в одно слово с использованием ограничения на экспорт в многопроцессорных системах.
_safe_fetch Обеспечивает атомарное чтение переменной размером в одно слово с использованием ограничения на импорт в многопроцессорных системах. Ограничение на импорт гарантирует, что считанное значение не является устаревшим значением, полученным ранее при выборке с упреждением. Эта процедура используется редко.

Пример служб блокировки

Процедуры блокировки с поддержкой многопроцессорных систем могут применяться для создания высокоуровневых процедур блокировки без использования библиотеки нитей. В этом примере показана частичная реализация процедур, аналогичных процедурам pthread_mutex_lock и pthread_mutex_unlock из библиотеки нитей.

#include <sys/atomic_op.h>  /* элементарные операции блокировки */
#define SUCCESS          0
#define FAILURE          -1
#define LOCK_FREE        0
#define LOCK_TAKEN       1

typdef struct {
        atomic_p         lock;   /* слово блокировки */
        tid_t            owner;  /* идентификатор владельца блокировки */
        ...                      /* поля, относящиеся к конкретной реализации */
} my_mutex_t;

...

int my_mutex_lock(my_mutex_t *mutex)
{
tid_t   self;   /* идентификатор вызывающей нити */
  
        /*
        Выполнение различных проверок:
          допустимо ли значение указателя взаимной блокировки?
          инициализирована ли взаимная блокировка?
        */
        ...

        /* проверка того, что взаимная блокировка не принадлежит
                                            вызывающей нити */
        self = thread_self();
        if (mutex->owner == self)
                return FAILURE;

        /*
        Выполнение атомарной операции проверки и установки в цикле.
        В этой версии - освобождать процессор при неудачной попытке.
        В другом варианте возможна непрерывная проверка
                 или освобождение процессора после фиксированного числа попыток.
        */
        while (!_check_lock(&mutex->lock, LOCK_FREE, LOCK_TAKEN))
                yield();

        mutex->owner = self;
        return SUCCESS;
} /* конец my_mutex_lock */

int my_mutex_unlock(my_mutex_t *mutex)
{
        /*
        Выполнение различных проверок:
          допустимо ли значение указателя взаимной блокировки?
          инициализирована ли взаимная блокировка?
        */
        ...

        /* проверка того, что взаимная блокировка не принадлежит
                                            вызывающей нити */
        if (mutex->owner != thread_self())
                return FAILURE;

        _clear_lock(&mutex->word, LOCK_FREE);
        return SUCCESS;
} /* конец my_mutex_unlock */

Связанная информация

Программирование в многопроцессорных системах: Обзор (Глава 10, Программирование в многопроцессорных системах)


[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]