Рубиновые семафоры?

Я работаю над реализацией проблемы "Fair Barbershop" в Ruby. Это для присвоения класса, но я не ищу никаких раздаточных материалов. Я искал как сумасшедший, но я не могу найти реализацию Ruby семафоров, которые отражают те, что найдены в C.

Я знаю, что есть Mutex, и это здорово. Единственная реализация, делает именно то, что должен делать этот семафор.

Тогда существуют переменные состояния. Я думал, что это будет отлично работать, но, глядя на них, они требуют Mutex для каждого вызова ожидания, который выглядит так, как будто я не могу вводить числовые значения в семафор (как, например, у меня семь парикмахерских, 3 парикмахеры и т.д.).

Мне кажется, мне нужен счетный семафор, но я думаю, что это немного странно, что Ruby не может (из того, что я могу найти) содержать такой класс в своем ядре. Может ли кто-нибудь помочь указать мне в правильном направлении?

Ответы

Ответ 1

Благодаря @x3ro для его ссылки. Это указывало мне в правильном направлении. Однако с реализацией Фукумото (по крайней мере, для rb1.9.2) Thread.критический недоступен. Кроме того, мои попытки заменить Thread.критические вызовы Thread.exclusive {} просто привели к взаимоблокировкам. Оказывается, существует предлагаемый патч Semaphore для Ruby (который я связал ниже), который решил проблему, заменив Thread.exclusive {} на Mutex:: synchronize {}, среди нескольких других настроек. Благодаря @x3ro для толкания меня в правильном направлении.

http://redmine.ruby-lang.org/attachments/1109/final-semaphore.patch

Ответ 2

Если вы используете JRuby, вы можете импортировать семафоры с Java, как показано в в этой статье.

require 'java'

java_import 'java.util.concurrent.Semaphore'

SEM = Semaphore.new(limit_of_simultaneous_threads)
SEM.acquire #To decrement the number available
SEM.release #To increment the number available

Ответ 3

Здесь http://sysvipc.rubyforge.org/SysVIPC.html, который дает вам семафоры SysV. Ruby идеально подходит для устранения недостатков API семафоров SysV, а семафоры SysV - лучшие из них - это семафоры между процессами, вы можете использовать SEM_UNDO, чтобы даже SIGKILL не испортили ваше глобальное состояние (семафоры POSIX interprocess не имеют этого), а с помощью семафоров SysV вы можете выполнять атомарные операции на нескольких семафорах сразу, пока они находятся в одном наборе семафоров.

Что касается межпоточных семафоров, то они должны быть прекрасно эмулируемыми с переменными состояния и мьютексами. (См. Ссылку Bernanrdo Martinez, как это можно сделать).

Ответ 5

Поскольку другие ссылки здесь не работают для меня, я решил быстро взломать что-то вместе. Я не тестировал это, поэтому вход и исправления приветствуются. Это основано просто на идее о том, что Mutex является двоичным семафором, поэтому Семафор представляет собой набор мьютексов.

https://gist.github.com/3439373

Ответ 6

поскольку concurrent-ruby является стабильным (более 1.0) и широко используется, поэтому лучшим (и переносимым по Ruby impls) решением является использование Concurrent::Semaphore класс