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

Это внутренне обрабатывает создание и выполнение Proc, что позволяет сделать код гораздо более читаемым. Использование методов с блоками, например 4.times { |idx| spawn { puts idx } }, работает как положено. Этот сценарий представляет собой проблему только при ссылке на одну и ту же локальную переменную, переменную класса или экземпляра во время итерации. Это также яркий пример того, почему совместное использование состояния непосредственно внутри волокон считается плохой практикой. Правильный способ сделать это — использовать каналы, которые мы рассмотрим в следующем разделе.

<p>Использование каналов для безопасной передачи данных</p>

Если совместное использование переменных между волокнами не является правильным способом взаимодействия между волокнами, то что? Ответ – каналы. Канал — это способ связи между волокнами без необходимости беспокоиться об условиях гонки, блокировках, семафорах или других специальных структурах. Давайте посмотрим на следующий пример:

input_channel = Channel(Int32).new

output_channel = Channel(Int32).new

spawn do

    output_channel.send input_channel.receive * 2

end

input_channel.send 2

puts output_channel.receive

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

Давайте посмотрим на другой пример, который сделает поведение более понятным:

channel = Channel(Int32).new

spawn do

  loop do

    puts "Waiting"

    sleep 0.5

  end

end

spawn do

  sleep 2

  channel.send channel.receive * 2

  sleep 1

  channel.send channel.receive * 3

  end

channel.send 2

puts channel.receive

channel.send 3

puts channel.receive

Запуск программы приводит к следующему выводу:

Waiting

Waiting

Waiting

Waiting

4

Waiting

Waiting

9

Первые результаты отправки и получения во втором волокне выполняются первыми. Однако первая строка — это sleep 2, поэтому она делает именно это. Поскольку спящий режим является блокирующей операцией, планировщик Crystal выполнит следующее ожидающее волокно, то есть то, которое печатает Waiting, а затем в цикле ожидает полсекунды. Это сообщение выводится четыре раза, что соответствует двухсекундному спящему режиму, за которым следует ожидаемый результат 4. Затем выполнение возвращается ко второму волокну, но сразу же переходит к первому волокну из-за sleep 1, что печатает Ожидание еще дважды, прежде чем отправить ожидаемый вывод 9 обратно в канал.

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

С другой стороны, буферизованный канал не будет переключаться на другое волокно при вызове отправки, если буфер не заполнен. Буферизованный канал можно создать, передав размер буфера конструктору канала. Например, взгляните на следующее:

channel = Channel(Int32).new 2

spawn do

  puts "Before send 1"

  channel.send 1

  puts "Before send 2"

  channel.send 2

  puts "Before send 3"

  channel.send 3

  puts "After send"

end

3.times do

  puts channel.receive

end

Это выведет следующее:

Before send 1

Before send 2

Before send 3

After send

1

2

3

Теперь, если мы запустим тот же код с небуферизованным каналом, результат будет следующий:

Before send 1

Before send 2

1

2

Before send 3

After send

3

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

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

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

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

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

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

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

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

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