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

на главную

Жанры

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

sleep rand(0)

puts "#{n}: (...играет...)"

sleep rand(0)

puts "#{n}: Я закончил."

@music.synchronize do

@violins_free += 1

@violin.signal if @violins_free == 1

@bows_free += 1

@bow.signal if @bows_free == 1

end

 end

end

threads = []

3.times {|i| threads << Thread.new { musician(i) } }

threads.each {|t| t.join }

Мы

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

13.2.5. Другие способы синхронизации

Еще один механизм синхронизации - это монитор, который в Ruby реализован в библиотеке

monitor.rb
. Это более развитый по сравнению с мьютексом механизм, основное отличие состоит в том, что захваты одного и того же мьютекса не могут быть вложенными, а монитора — могут.

Тривиальный случай возникновения такой ситуации вряд ли возможен. В самом деле, кто станет писать такой код:

@mutex = Mutex.new

@mutex.synchronize do

 @mutex.synchronize do

#...

 end

end

Но нечто подобное может произойти в сложной программе (или при рекурсивном вызове метода). Какова бы ни была причина, последствием будет тупиковая ситуация. Уход от нее — одно из достоинств модуля-примеси

Monitor
.

@mutex = Mutex.new

def some_method

 @mutex.synchronize do

#...

some_other_method # Тупиковая ситуация!

 end

end

def some_other_method

 @mutex.synchronize do

#...

 end

end

Модуль-примесь

Monitor
обычно применяется для расширения объекта. Для создания условной переменной предназначен метод
new_cond
.

Класс

ConditionVariable
в библиотеке
monitor.rb
дополнен по сравнению с определением в библиотеке
thread
. У него есть методы
wait_until
и
wait_while
, которые блокируют поток в ожидании выполнения условия. Кроме того, возможен тайм-аут при ожидании, поскольку у
метода
wait
имеется параметр
timeout
, равный количеству секунд (по умолчанию
nil
).

Поскольку примеры работы с потоками у нас кончаются, то в листинге 13.5 мы предлагаем реализацию классов

Queue
и
SizedQueue
с помощью монитора. Код приводится с разрешения автора, Шуго Маэда (Shugo Maeda).

Листинг 13.5. Реализация класса Queue с помощью монитора

# Автор: Shugo Maeda

require 'monitor'

class Queue

 def initialize

@que = []

@monitor = Monitor.new

@empty_cond = @monitor.new_cond

 end

 def enq(obj)

@monitor.synchronize do

@que.push(obj)

@empty_cond.signal

end

 end

 def deq

@monitor.synchronize do

while @que.empty?

@empty_cond.wait

end

return @que.shift

end

 end

end

class SizedQueue < Queue

 attr :max

 def initialize(max)

super

@max = max

@full_cond = @monitor.new_cond

 end

 def enq(obj)

@monitor.synchronize do

while @que.length >= @max

@full_cond.wait

end

super(obj)

end

 end

 def deq

@monitor.synchronize do

obj = super

if @que.length < @max

@full_cond.signal

end

return obj

end

 end

 def max=(max)

@monitor.synchronize do

@max = max

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

Сотник

Ланцов Михаил Алексеевич
4. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Сотник

Магнат

Шимохин Дмитрий
4. Подкидыш
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Магнат

Наследник старого рода

Шелег Дмитрий Витальевич
1. Живой лёд
Фантастика:
фэнтези
8.19
рейтинг книги
Наследник старого рода

Моров. Том 4

Кощеев Владимир
3. Моров
Фантастика:
фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Моров. Том 4

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Иной. Том 1. Школа на краю пустыни

Amazerak
1. Иной в голове
Фантастика:
боевая фантастика
рпг
аниме
5.75
рейтинг книги
Иной. Том 1. Школа на краю пустыни

Точка Бифуркации III

Смит Дейлор
3. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Точка Бифуркации III

Призыватель нулевого ранга. Том 3

Дубов Дмитрий
3. Эпоха Гардара
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Призыватель нулевого ранга. Том 3

Адвокат Империи 14

Карелин Сергей Витальевич
14. Адвокат империи
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Адвокат Империи 14

Травница Его Драконейшества

Рель Кейлет
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Травница Его Драконейшества

Контуженый

Бакшеев Сергей
Детективы:
боевики
5.00
рейтинг книги
Контуженый

Технарь

Муравьёв Константин Николаевич
1. Технарь
Фантастика:
космическая фантастика
попаданцы
7.13
рейтинг книги
Технарь

Князь Андер Арес 4

Грехов Тимофей
4. Андер Арес
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Князь Андер Арес 4

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи