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

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

Жанры

Программирование на языке Ruby
Шрифт:

buff = SizedQueue.new(25)

upper1 = buff.max #25

# Увеличить размер очереди...

buff.max = 50

upper2 = buff.max # 50

В листинге 13.3 приведено решение задачи о производителе и потребителе. Для производителя задержка (аргумент sleep) чуть больше, чем для потребителя, чтобы единицы продукции «накапливались».

Листинг 13.3. Задача о производителе и потребителе

require 'thread'

buffer = SizedQueue.new(2)

producer = Thread.new do

 item = 0

 loop do

sleep rand 0

puts "Производитель произвел #{item}"

buffer.enq item

item += 1

 end

end

consumer = Thread.new do

 loop do

sleep (rand 0)+0.9

item = buffer.deq

puts "Потребитель потребил #{item}"

puts " ожидает = #{buffer.num_waiting}"

 end

end

sleep 60 # Работать одну минуту, потом завершить оба потока.

Чтобы поместить элемент в очередь и извлечь из нее, рекомендуется применять соответственно методы

enq
и
deq
. Можно было бы для помещения в очередь пользоваться также методом
push
, а для извлечения — методами
pop
и
shift
, но их названия не так мнемоничны в применении к очередям.

Метод

empty?
проверяет, пуста ли очередь, а метод
clear
опустошает ее. Метод
size
его синоним
length
) возвращает число элементов в очереди.

# Предполагается, что другие потоки не мешают...

buff = Queue.new

buff.enq "one"

buff.enq "two"

buff.enq "three"

n1 = buff.size # 3

flag1 = buff.empty? # false

buff.clear

n2 = buff.size # 0

flag2 = buff.empty? # true

Метод

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

Необязательный параметр

non_block
метода
deq
в классе
Queue
по умолчанию равен
false
. Если же он равен
true
, по при попытке извлечь элемент из пустой очереди он не блокирует поток, а возбуждает исключение
ThreadError
.

13.2.4. Условные переменные

Да зовите моих скрипачей, трубачей...

«Веселый король» (детский стишок) [16]

Условная переменная — это, по существу, очередь потоков. Они используются в сочетании с мьютексами для лучшего управления синхронизацией потоков.

Условная переменная всегда ассоциируется с каким-то мьютексом. Ее назначение — освободить мьютекс до тех пор, пока не начнет выполняться определенное условие. Представьте себе ситуацию, когда поток захватил мьютекс, но не готов продолжать выполнение. Тогда он может заснуть под контролем условной переменной, ожидая, что будет разбужен, когда условие станет истинным.

16

Пер. С. Маршака. — Прим. ред.

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

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

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

Код представлен в листинге 13.4.

Листинг 13.4. Три скрипача

require 'thread'

@music = Mutex.new

@violin = ConditionVariable.new

@bow = ConditionVariable.new

@violins_free = 2

@bows_free = 1

def musician(n)

 loop do

sleep rand(0)

@music.synchronize do

@violin.wait(@music) while @violins_frее == 0

@violins_free -= 1

puts "#{n} владеет скрипкой"

puts "скрипок #@violins_frее, смычков #@bows_free"

@bow.wait(@music) while @bows_free == 0

@bows_free -= 1

puts "#{n} владеет смычком"

puts "скрипок #@violins_free, смычков #@bows_free"

end

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

Как я строил магическую империю 14

Зубов Константин
14. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Как я строил магическую империю 14

Летос

Пехов Алексей Юрьевич
1. Синее пламя
Фантастика:
фэнтези
боевая фантастика
8.72
рейтинг книги
Летос

Я все еще князь. Книга XXI

Дрейк Сириус
21. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я все еще князь. Книга XXI

Имя нам Легион. Том 18

Дорничев Дмитрий
18. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 18

Рассвет русского царства 3

Грехов Тимофей
3. Новая Русь
Фантастика:
историческое фэнтези
альтернативная история
5.00
рейтинг книги
Рассвет русского царства 3

Ермак. Телохранитель

Валериев Игорь
2. Ермак
Фантастика:
альтернативная история
7.50
рейтинг книги
Ермак. Телохранитель

Средоточие

Кораблев Родион
20. Другая сторона
Фантастика:
боевая фантастика
космическая фантастика
постапокалипсис
рпг
фантастика: прочее
попаданцы
5.00
рейтинг книги
Средоточие

Мастер 8

Чащин Валерий
8. Мастер
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Мастер 8

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX

Наследник 2

Шимохин Дмитрий
2. Старицкий
Фантастика:
попаданцы
альтернативная история
фэнтези
5.75
рейтинг книги
Наследник 2

Вернуть невесту. Ловушка для попаданки 2

Ардова Алиса
2. Вернуть невесту
Любовные романы:
любовно-фантастические романы
7.88
рейтинг книги
Вернуть невесту. Ловушка для попаданки 2

Как я строил магическую империю 15

Зубов Константин
15. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
5.00
рейтинг книги
Как я строил магическую империю 15

Меченный смертью. Том 2

Юрич Валерий
2. Меченный смертью
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Меченный смертью. Том 2

Двойник Короля 2

Скабер Артемий
2. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Двойник Короля 2