Чтение онлайн

на главную - закладки

Жанры

Язык программирования Python
Шрифт:

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

Семафоры

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

уменьшающийся с каждым вызовом метода acquire и увеличивающийся при каждом вызове release. Счетчик не может стать меньше нуля, поэтому в таком состоянии потокам приходится ждать, как и в случае с замками, пока значение счетчика не увеличится.

Конструктор класса threading.Semaphore принимает в качестве (необязательного) аргумента начальное состояние счетчика (по умолчанию оно равно 1, что соответствует замку класса Lock). Методы acquire и release действуют аналогично описанным выше одноименным методам у замков.

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

Листинг

from threading import BoundedSemaphore

maxconnections = 5

# Подготовка семафора

pool_sema = BoundedSemaphore(value=maxconnections)

# Внутри потока:

pool_sema.acquire

conn = connectdb

# … использование соединения …

conn.close

pool_sema.release

Таким образом, применяется не более пяти соединений с базой данных. В примере использован класс threading.BoundedSemaphore. Экземпляры этого класса отличаются от экземпляров класса threading.Semaphore тем, что не дают сделать release больше, чем сделан acquire.

События

Еще одним способом коммуникации между объектами являются события. Экземпляры класса threading.Event могут быть использованы для передачи информации о наступлении некоторого события от одного потока одному или нескольким другим потокам. Объекты–события имеют внутренний флаг, который может находиться в установленном или сброшенном состоянии. При своем создании флаг события находится в сброшенном состоянии. Если флаг в установленном состоянии, ожидания не происходит: поток, вызвавший метод wait для ожидания события, просто продолжает свою работу. Ниже приведены методы экземпляров класса threading.Event:

setУстанавливает внутренний флаг, сигнализирующий о наступлении события. Все ждущие данного события потоки выходят из состояния ожидания.

clearСбрасывает флаг. Все события, которые вызывают метод wait этого объекта–события, будут находиться в состоянии ожидания до тех пор, пока флаг сброшен, или по истечении заданного таймаута.

isSetВозвращает состояние флага.

wait([timeout])Переводит поток в состояние ожидания, если флаг сброшен, и сразу возвращается, если флаг установлен. Аргумент timeout задает таймаут в секундах,

по истечении которого ожидание прекращается, даже если событие не наступило.

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

Условия

Более сложным механизмом коммуникации между потоками является механизм условий. Условия представляются в виде экземпляров класса threading.Condition и, подобно только что рассмотренным событиям, оповещают потоки об изменении некоторого состояния. Конструктор класса threading.Condition принимает необязательный параметр, задающий замок класса threading.Lock или threading.RLock. По умолчанию создается новый экземпляр замка класса threading.RLock. Методы объекта–условия описаны ниже:

acquire(…)Запрашивает замок. Фактически вызывается одноименный метод принадлежащего объекту–условию объекта–замка.

releaseСнимает замок.

wait([timeout])Переводит поток в режим ожидания. Этот метод может быть вызван только в том случае, если вызывающий его поток получил замок. Метод снимает замок и блокирует поток до появления объявлений, то есть вызовов методов notify и notifyAll другими потоками. Необязательный аргумент timeout задает таймаут ожидания в секундах. При выходе из ожидания поток снова запрашивает замок и возвращается из метода wait.

notifyВыводит из режима ожидания один из потоков, ожидающих данные условия. Метод можно вызвать, только овладев замком, ассоциированным с условием. Документация предупреждает, что в будущих реализациях модуля из целей оптимизации этот метод будет прерывать ожидание сразу нескольких потоков. Сам по себе метод notify не приводит к продолжению выполнения ожидавших условия потоков, так как этому препятствует занятый замок. Потоки получают управление только после снятия замка потоком, вызвавшим метод notify.

notifyAllЭтот метод аналогичен методу notify, но прерывает ожидание всех ждущих выполнения условия потоков.

В следующем примере условия используются для оповещения потоков о прибытии новой порции данных (организуется связь производитель — потребитель, producer — consumer):

Листинг

import threading

cv = threading.Condition

class Item:

«"«Класс–контейнер для элементов, которые будут потребляться

в потоках»""

def __init__(self):

self._items = []

def is_available(self):

return len(self._items) > 0

def get(self):

return self._items.pop

def make(self, i):

self._items.append(i)

item = Item

def consume:

«"«Потребление очередного элемента (с ожиданием его появления)»""

cv.acquire

while not item.is_available:

cv.wait

it = item.get

cv.release

return it

def consumer:

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

Возлюби болезнь свою

Синельников Валерий Владимирович
Научно-образовательная:
психология
7.71
рейтинг книги
Возлюби болезнь свою

Надуй щеки!

Вишневский Сергей Викторович
1. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки!

На границе империй. Том 8. Часть 2

INDIGO
13. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8. Часть 2

Законы Рода. Том 4

Андрей Мельник
4. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 4

Кодекс Охотника. Книга XXIX

Винокуров Юрий
29. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXIX

Убивать чтобы жить 5

Бор Жорж
5. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 5

Телохранитель Генсека. Том 1

Алмазный Петр
1. Медведев
Фантастика:
попаданцы
альтернативная история
7.00
рейтинг книги
Телохранитель Генсека. Том 1

Варяг

Мазин Александр Владимирович
1. Варяг
Фантастика:
альтернативная история
9.10
рейтинг книги
Варяг

Симфония теней

Злобин Михаил
3. Хроники геноцида
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Симфония теней

Газлайтер. Том 23

Володин Григорий Григорьевич
23. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 23

Вдова на выданье

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Вдова на выданье

Монстр из прошлого тысячелетия

Еслер Андрей
5. Соприкосновение миров
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Монстр из прошлого тысячелетия

Древесный маг Орловского княжества

Павлов Игорь Васильевич
1. Орловское княжество
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества

Я все еще барон

Дрейк Сириус
4. Дорогой барон!
Фантастика:
боевая фантастика
5.00
рейтинг книги
Я все еще барон