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

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

15 голосов
/ 30 марта 2011

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

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

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

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

Ответы [ 6 ]

4 голосов
/ 27 сентября 2013

Если вы используете 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
2 голосов
/ 12 мая 2015

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

Как и в случае семафоров между потоками, они должны идеально эмулироваться с переменными условийи мьютексы.(См. Ссылку Бернандро Мартинеса о том, как это можно сделать).

1 голос
/ 14 января 2015

Я также нашел этот код: https://gist.github.com/pettyjamesm/3746457

Вероятно, кому-то может понравиться этот другой вариант.

0 голосов
/ 13 июня 2016

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

0 голосов
/ 23 августа 2012

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

https://gist.github.com/3439373

0 голосов
/ 30 марта 2011

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

http://redmine.ruby -lang.org / вложение / 1109 / окончательный semaphore.patch

...