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

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

Жанры

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

@full_cond.broadcast

end

 end

end

Еще один вариант синхронизации (двузначную блокировку со счетчиком) предлагает библиотека

sync.rb
. В ней определен модуль
Sync_m
, который можно применять вместе с ключевыми словами
include
и
extend
(как и
Mutex_m
). Этот модуль содержит методы
locked?
,
shared?
,
exclusive?
,
lock
,
unlock
и
try_lock
.

13.2.6. Тайм-аут при выполнении операций

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

Библиотека

timeout.rb
предлагает решение этой проблемы на основе потоков (см. листинг 13.6). С методом
timeout
ассоциирован выполняемый блок. Если истечет заданное число секунд, метод возбуждает исключение
TimeoutError
, которое можно перехватить с помощью
rescue
.

Листинг 13.6. Пример тайм-аута

require 'timeout.rb'

flag = false

answer = nil

begin

 timeout(5) do

puts "Хочу печенье!"

answer = gets.chomp

flag = true

 end

 rescue TimeoutError

 flag = false

end

if flag

 if answer == "cookie"

puts "Спасибо! Хрум, хрум..."

 else

puts "Это же не печенье!"

exit

 end

else

 puts "Эй, слишком медленно!"

 exit

end

puts "До встречи..."

13.2.7. Ожидание события

Часто один или несколько потоков следят за «внешним миром», а остальные выполняют полезную работу. Все примеры в этом разделе надуманные, но общий принцип они все же иллюстрируют.

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

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

$flag = false

work1 = Thread.new { job1 }

work2 = Thread.new { job2 }

work3 = Thread.new { job3 }

thread4 = Thread.new { Thread.stop; job4 }

thread5 = Thread.new { Thread.stop; job5 }

watcher = Thread.new do

 loop do

sleep 5

if $flag

thread4.wakeup

thread5.wakeup

Thread.exit

end

 end

end

Если

в какой-то момент выполнения метода
job
, переменная
$flag
станет равной
true
, то в течение пяти секунд после этого потоки
thread4
и
thread5
гарантированно запустятся. После этого поток
watcher
завершается.

В следующем примере мы ждем создания файла. Каждые 30 секунд проверяется его существование, и как только файл появится, мы запускаем новый поток. Тем временем остальные потоки занимаются своим делом. На самом деле ниже мы наблюдаем за тремя разными файлами.

def waitfor(filename)

 loop do

if File.exist? filename

file_processor = Thread.new { process_file(filename) }

Thread.exit

else

sleep 30

end

 end

end

waiter1 = Thread.new { waitfor("Godot") }

sleep 10

waiter2 = Thread.new { waitfor("Guffman") }

sleep 10

headwaiter = Thread.new { waitfor("head") }

# Основной поток занимается другими делами...

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

13.2.8. Продолжение обработки во время ввода/вывода

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

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

Предположим, что итератор

predict_move
генерирует вероятные ходы человека (и ответные ходы программы). Тогда в момент, когда человек сделает ход, не исключено, что у компьютера уже будет готов ответ.

scenario = {} # Хэш ход-ответ.

humans_turn = true

thinking_ahead = Thread.new(board) do

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

Цикл романов "Целитель". Компиляция. Книги 1-17

Большаков Валерий Петрович
Целитель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Цикл романов Целитель. Компиляция. Книги 1-17

Гримуар темного лорда V

Грехов Тимофей
5. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда V

Отщепенец

Ермоленков Алексей
1. Отщепенец
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Отщепенец

Санек

Седой Василий
1. Санек
Фантастика:
попаданцы
альтернативная история
4.00
рейтинг книги
Санек

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Приказано выжить!

Малыгин Владимир
1. Другая Русь
Фантастика:
боевая фантастика
попаданцы
альтернативная история
7.09
рейтинг книги
Приказано выжить!

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

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

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

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

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

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

Афганский рубеж

Дорин Михаил
1. Рубеж
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Афганский рубеж

Найденыш

Шмаков Алексей Семенович
2. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Найденыш

Бастард Императора. Том 10

Орлов Андрей Юрьевич
10. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 10

Первый среди равных. Книга V

Бор Жорж
5. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга V

Эволюционер из трущоб. Том 7

Панарин Антон
7. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 7