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

на главную

Жанры

Программирование на языке 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

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

Дважды одаренный

Тарс Элиан
1. Дважды одаренный
Фантастика:
альтернативная история
аниме
фэнтези
фантастика: прочее
попаданцы
5.25
рейтинг книги
Дважды одаренный

Неучтенный элемент. Том 12

NikL
12. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 12

Второгодка. Книга 4. Подавать холодным

Ромов Дмитрий
4. Второгодка
Фантастика:
героическая фантастика
альтернативная история
сказочная фантастика
5.00
рейтинг книги
Второгодка. Книга 4. Подавать холодным

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

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

Бронзовый мальчик

Крапивин Владислав Петрович
2. Паруса Эспады
Детские:
детские приключения
8.62
рейтинг книги
Бронзовый мальчик

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

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

Сравнительные жизнеописания

Плутарх
Документальная литература:
биографии и мемуары
8.85
рейтинг книги
Сравнительные жизнеописания

Лунный бассейн. Металлическое чудовище (сборник)

Меррит Абрахам Грэйс
2. Абрахам Меррит. Собрание сочинений в 5 томах
Фантастика:
ужасы и мистика
5.00
рейтинг книги
Лунный бассейн. Металлическое чудовище (сборник)

Возвращение Томаса. Башня-2 (сборник)

Никитин Юрий Александрович
Фантастика:
фэнтези
7.00
рейтинг книги
Возвращение Томаса. Башня-2 (сборник)

Миры Источника. Трилогия

Авраменко Олег Евгеньевич
19. В одном томе
Фантастика:
фэнтези
5.60
рейтинг книги
Миры Источника. Трилогия

Мастер големов

Назимов Константин Геннадьевич
4. Травник
Фантастика:
фэнтези
5.25
рейтинг книги
Мастер големов

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Дважды одаренный. Том V

Тарс Элиан
5. Дважды одаренный
Фантастика:
аниме
альтернативная история
городское фэнтези
5.25
рейтинг книги
Дважды одаренный. Том V

Круг чтения. Афоризмы и наставления

Толстой Лев Николаевич
Золотой фонд эзотерики
Проза:
афоризмы
5.00
рейтинг книги
Круг чтения. Афоризмы и наставления