Книга: Программирование на языке Ruby
13.2.7. Ожидание события
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.1. Синхронизация с помощью критических секций
- 13.2.2. Синхронизация доступа к ресурсам (mutex.rb)
- 13.2.3. Предопределенные классы синхронизированных очередей
- 13.2.4. Условные переменные
- 13.2.5. Другие способы синхронизации
- 13.2.6. Тайм-аут при выполнении операций
- 13.2.7. Ожидание события
- 13.2.8. Продолжение обработки во время ввода/вывода
- 13.2.9. Реализация параллельных итераторов
- 13.2.10. Параллельное рекурсивное удаление
- Ожидание порта завершения ввода
- Простейшие события
- Создание рабочей области для собраний на основе календарного события
- События
- Как работают сценарии. События
- Ожидание процесса
- Глава пятая. Затянувшееся ожидание
- Листинг 5.4. (sem_pv.c) Ожидание и установка двоичного семафора
- Генерирование события оплаты
- Когда не нужно создавать процедур обработки события Click
- 10.5.1. Запуск и ожидание с помощью system()
- Ожидание завершения процесса