Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
13.2.6. Тайм-аут при выполнении операций
Часто встречается ситуация, когда на выполнение операции отводится определенное максимальное время. Это позволяет избежать бесконечных циклов и более строго контролировать порядок работы. Подобная возможность очень полезна, в частности, в сетевых приложениях, где ответ от сервера может и не прийти.
Библиотека
timeout.rbtimeoutTimeoutErrorrescuerequire 'timeout.rb'flag = falseanswer = nilbegin timeout(5) do puts "Хочу печенье!" answer = gets.chomp flag = true end rescue TimeoutError flag = falseendif flag if answer == "cookie" puts "Спасибо! Хрум, хрум..." else puts "Это же не печенье!" exit endelse puts "Эй, слишком медленно!" exitendputs "До встречи..."13.2.7. Ожидание события
Часто один или несколько потоков следят за «внешним миром», а остальные выполняют полезную работу. Все примеры в этом разделе надуманные, но общий принцип они все же иллюстрируют.
В следующем примере прикладную задачу решают три потока. Четвертый поток каждые пять секунд просыпается, проверяет глобальную переменную
$flag$flag = falsework1 = 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 endendЕсли в какой-то момент выполнения метода
job$flagtruethread4thread5watcherВ следующем примере мы ждем создания файла. Каждые 30 секунд проверяется его существование, и как только файл появится, мы запускаем новый поток. Тем временем остальные потоки занимаются своим делом. На самом деле ниже мы наблюдаем за тремя разными файлами.
def waitfor(filename) loop do if File.exist? filename file_processor = Thread.new { process_file(filename) } Thread.exit else sleep 30 end endendwaiter1 = Thread.new { waitfor("Godot") }sleep 10waiter2 = Thread.new { waitfor("Guffman") }sleep 10headwaiter = Thread.new { waitfor("head") }# Основной поток занимается другими делами...Есть много ситуаций, когда поток должен ожидать внешнего события (например, в сетевых приложениях так бывает, когда сервер на другом конце соединения работает медленно или ненадежно).
13.2.8. Продолжение обработки во время ввода/вывода
Часто приложению приходится выполнять одну или более длительных операций ввода/вывода. Прежде всего, речь идет о вводе данных с клавиатуры, поскольку человек печатает куда медленнее, чем вращается диск. Это время можно употребить на пользу с помощью потоков.
Возьмем, к примеру, шахматную программу, которая должна ждать, пока человек сделает ход. Конечно, мы можем изложить только сам принцип, не вдаваясь в технические детали.
Предположим, что итератор
predict_movescenario = {} # Хэш ход-ответ.humans_turn = truethinking_ahead = Thread.new(board) do predict_move do |m| scenario[m] = my_response(board,m) Thread.exit if humans_turn == false endendhuman_move = get_human_move(board)
