Вход/Регистрация
Программирование на языке Ruby
вернуться

Фултон Хэл

Шрифт:

# ...

К пространству кортежей в Rinda применимы пять операций:

read
,
read_all
,
write
,
take
и
notify
.

Операция чтения

read
позволяет получить один кортеж. Но способ идентификации кортежа не вполне очевиден: необходимо задать кортеж, соответствующий искомому; при этом
nil
соответствует любому значению.

t1 = ts.read [:Sum,nil] # Может извлечь, например, [:Sum, 14].

Обычно операция

read
блокирует выполнение программы (для синхронизации). Чтобы быстро проверить существование кортежа, можно выполнить неблокирующее чтение, задав нулевой тайм-аут:

t2 = ts.read [:Result,nil],0 # Возбуждает исключение, если кортеж

# не существует.

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

read_all
, который возвращает массив:

tuples = ts.read_all [:Foo, nil, nil]

tuples.each do |t|

# ...

end

Метод

read_all
не принимает второго параметра. Он всегда блокирует программу, если не найдено ни одного подходящего кортежа.

Операция

take
— это чтение, за которым следует удаление. Иными словами, метод
take
удаляет кортеж из пространства кортежей и возвращает его вызывающей программе:

t = ts.take [:Sum, nil] # Кортежа больше нет в пространстве кортежей.

Может возникнуть вопрос, почему не существует явного способа удаления. Надо полагать, что этой цели служит метод take.

Метод

write
помещает кортеж в пространство кортежей. Второй параметр показывает, сколько секунд кортеж может существовать, прежде чем система сочтет, что срок его хранения истек. (По умолчанию его значение равно
nil
, то есть срок хранения не ограничен.)

ts.write [:Add, 5, 9] # Хранить "вечно".

ts.write [:Foo, "Bar"], 10 # Хранить 10 секунд.

Здесь уместно будет сказать несколько слов о синхронизации. Предположим, что два клиента пытаются одновременно забрать (

take
) один и тот же кортеж. Одному это удастся, а другой будет заблокирован. Если первый клиент затем изменит кортеж и запишет (
write
) его обратно в хранилище, то второй получит модифицированную версию. Можно считать, что операция «обновления» — это последовательность
take
и
write
, которая не приводит к потере данных. Конечно, как и при любом варианте многопоточного программирования, нужно позаботиться о том, чтобы не возникали тупиковые ситуации.

Метод

notify
позволяет следить за пространством кортежей и получать уведомления, когда над интересующим вас кортежем была выполнена какая-то операция. Этот метод возвращает объект
NotifyTemplateEntry
и может наблюдать на операциями четырех видов:

• 

write
;

• 

take
;

• удаление (когда истекает срок хранения кортежа);

• закрытие (когда истекает срок хранения объекта

NotifyTemplateEntry
).

Поскольку операция чтения ничего не изменяет, то система не поддерживает уведомлений о чтениях. В листинге 20.4 приведен пример использования notify.

Листинг 20.4. Уведомление в системе Rinda

require 'rinda/tuplespace'

ts = Rinda::TupleSpace.new

alberts = ts.notify "write", ["Albert", nil]

martins = ts.notify "take", ["Martin", nil]

thr1 = Thread.new do

 alberts.each {|op,t| puts "#{op}: #{t.join(' ')}" }

end

thr2 = Thread.new do

 martins.each {|op,t| puts "#{op}: #{t.join(' ')}" }

end

sleep 1

ts.write ["Martin", "Luther"]

ts.write ["Albert", "Einstein"]

ts.write ["Martin", "Fowler"]

ts.write ["Alberf, "Schweitzer"]

ts.write ["Martin", "Scorsese"]

ts.take ["Martin", "Luther"]

# Выводится:

  • Читать дальше
  • 1
  • ...
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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