Читаем Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI полностью

Goodbye program!

Но подождите! Что случилось с сообщением в fiber, которое мы создали? Ответ можно найти в начале главы, в разделе "Определение fiber". Ключевые слова появятся в какой-то момент в будущем. Создание fiber не приводит к немедленному выполнению fiber. Вместо этого он запланирован для выполнения планировщиком Crytal. Планировщик выполнит следующий поставленный в очередь fiber при первой возможности. В этом примере такой возможности никогда не возникает, поэтому fiber никогда не выполняется.

Это важная деталь для понимания того, как работает параллелизм в Crystal, а также того, почему природа IO, рассмотренная в Главе 5 "Операции ввода/вывода", может быть настолько полезной. К числу факторов, которые могут привести к выполнению другого fiber, относятся следующие:

• Метод sleep

Fiber.yield метод

• Операции, связанные с IO, такие как чтение/запись в файл или сокет

• Ожидание получения значения из канала

• Ожидание отправки значения в канал

• Когда текущее волокно завершит выполнение

Все эти параметры блокируют волокно, в результате чего другие волокна получают возможность выполниться. Например, добавьте sleep 1 после блока появления и перезапустите программу. Обратите внимание: на этот раз Hello from fiber! действительно печатается. Метод sleep сообщает планировщику, что он должен продолжить выполнение основного волокна через одну секунду. Тем временем он может свободно выполнить следующее волокно в очереди, которое в данном случае печатает наше сообщение.

Метод Fiber.yield, или sleep 0, даст тот же результат, но означает немного другое. При использовании метода sleep с целочисленным аргументом планировщик знает, что он должен вернуться к этому волокну в какой-то момент в будущем после того, как он достаточно отоспался. Однако использование Fiber.yield или sleep 0 позволит проверить, есть ли волокна, ожидающие выполнения, и если да, выполнить их. В противном случае это будет продолжаться без переключения. Такое поведение наиболее распространено, когда вы выполняете некоторую логику в узком цикле, но все же хотите дать возможность другим волокнам выполниться. Однако Fiber.yield просто сообщает планировщику, что вы можете запустить другое волокно, но не гарантирует, когда и если выполнение переключится обратно на это исходное волокно.

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

Продолжая предыдущий пример, вы можете захотеть использовать переменные внутри волокна, которые были определены за его пределами. Однако это плохая идея, поскольку она приводит к неожиданным результатам:

idx = 0

while idx < 4

    spawn do

        puts idx

    end

    idx += 1

end

Fiber.yield

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

• Волокна не выполняются немедленно.

• Каждое волокно ссылается на одну и ту же переменную.

Поскольку волокна не выполняются немедленно, они создаются при каждой итерации цикла while loop. После четырех раз значение idx достигает четырех и выходит из цикла while loop. Затем, поскольку каждое волокно ссылается на одну и ту же переменную, все они печатают текущее значение этой переменной, равное 4. Эту проблему можно решить, переместив порождение каждого волокна в отдельный процесс, который создаст замыкание, фиксирующее значение переменная на каждой итерации. Однако это далеко не идеально, поскольку в этом нет необходимости и ухудшается читаемость кода. Лучший способ справиться с этим — использовать альтернативную форму spawn, которая принимает вызов в качестве аргумента:

idx = 0

while idx < 4

    spawn puts idx

    idx += 1

end

Fiber.yield

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных