Вход/Регистрация
Разработка ядра Linux
вернуться

Лав Роберт

Шрифт:

static DECLARE_SEMAPHORE_GENERIC(name, count);

где

name
— имя переменной семафора, a
count
— счетчик семафора. Более короткая запись для создания взаимоисключающей блокировки (mutex), которая используются наиболее часто, имеет следующий вид.

static DECLARE_MUTEX(name);

где

name
— это снова имя переменной типа семафор. Чаще всего семафоры создаются динамически, как часть больших структур данных. В таком случае для инициализации семафора, который создается динамически и на который есть только непрямая ссылка через указатель, необходимо использовать функцию

sema_init(sem, count);

где

sem
— это указатель, a
count
— счетчик использования семафора. Аналогично для инициализации динамически создаваемой взаимоисключающей блокировки можно использовать функцию

init_MUTEX(sem);

Неизвестно, почему слово "mutex" в имени функции

init_MUTEX
выделено большими буквами и почему слово "init" идет перед ним, в то время как имя функции
sema_init
таких особенностей не имеет. Тем не менее ясно, что это выглядит не логично, и я приношу свои извинения за это несоответствие. Надеюсь, что после прочтения главы 7 ни у кого уже не будет вызывать удивление то, какие имена придумывают символам ядра.

Использование семафоров

Функция

down_interruptible
выполняет попытку захватить данный семафор. Если эта попытка неудачна, то задание переводится в состояние ожидания с флагом
TASK_INTERRUPTIBLE
. Из материала главы 3 следует вспомнить, что такое состояние процесса означает, что задание может быть возвращено к выполнению с помощью сигнала и что такая возможность обычно очень ценная. Если сигнал приходит в тот момент, когда задание ожидает на освобождение семафора, то задание возвращается к выполнению, а функция
down_interruptible
возвращает значение
– EINTR
. Альтернативой рассмотренной функции выступает функция
down
, которая переводит задание в состояние ожидания с флагом
TASK_UNINTERRUPTIBLE
. В большинстве случаев это нежелательно, так как процесс, который ожидает на освобождение семафора, не будет отвечать на сигналы. Поэтому функция
down_interruptible
используется значительно более широко, чем функция
down
. Да, имена этих функций, конечно, далеки от идеала.

Функция

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

Для освобождения захваченного семафора необходимо вызвать функцию

up
. Рассмотрим следующий пример.

/* объявление и описание семафора с именем mr_sem и

первоначальным значением счетчика, равным 1 */

static DECLARE_MUTEX(mr_sem);

...

if (down_interruptible(&mr_sem))

 /* получен сигнал и семафор не захвачен */

/* критический участок ... */

/* освободить семафор */

up(&mr_sem);

Полный список функций работы с семафорами приведен в табл. 9.5.

Таблица 9.5. Список функций работы с семафорами

Функция Описание
sema_init(struct semaphore*, int)
Инициализация динамически созданного семафора и установка для него указанного значения счетчика использования
init_MUTEX(struct semaphore*)
Инициализация динамически созданного семафора и установка его счетчика использования в значение 1
init_MUTEX_LOCKED (struct semaphore*)
Инициализация динамически созданного семафора и установка его счетчика использования в значение 0 (т.е. семафор изначально заблокирован)
down_interruptible(struct semaphore *)
Выполнить попытку захватить семафор и перейти в прерываемое состояние ожидания, если семафор находится в состоянии конфликта при захвате (contended)
down(struct semaphore*)
Выполнить попытку захватить семафор и перейти в непрерываемое состояние ожидания, если семафор находится в состоянии конфликта при захвате (contended)
down_trylock(struct semaphore*)
Выполнить попытку захватить семафор и немедленно возвратить ненулевое значение, если семафор находится в состоянии конфликта при захвате (contended)
up(struct semaphore*)
Освободить указанный семафор и возвратить к выполнению ожидающее задание, если такое есть

Семафоры чтения-записи

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

Семафоры чтения-записи представляются с помощью структуры

struct rw_semaphore
, которая определена в файле
<asm/rwsem.h>
. Статически определенный семафор чтения-записи может быть создан с помощью функции

static DECLARE_RWSEM(name);

где

name
— это имя нового семафора.

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

init_rwsem(struct rw_semaphore *sem);

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

down.
Рассмотрим следующий пример.

  • Читать дальше
  • 1
  • ...
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: