Существует много различных реализаций очередей производитель-потребитель, таких как queue.Queue .Они обычно отличаются по многим свойствам, как указано в этой превосходной статье Дмитрия Вьюкова.Как видите, возможны более 10 тысяч различных комбинаций.Алгоритмы, используемые для таких очередей, также сильно различаются в зависимости от требований.Невозможно просто расширить существующий алгоритм очереди, чтобы гарантировать дополнительные свойства, поскольку для этого обычно требуются разные внутренние структуры данных и разные алгоритмы.
Каналы Go предлагают относительно большое количество гарантированных свойств, поэтому эти каналы могут быть подходящимидля многих программ.Одним из самых сложных требований является поддержка одновременного чтения / блокировки на нескольких каналах (оператор select) и справедливый выбор канала, если более чем одна ветвь в операторе select может быть выполнена, так что не останется ни одного сообщения.,Python queue.Queue не предлагает эти функции, поэтому просто невозможно заархивировать такое же поведение с ним.
Итак, если вы хотите продолжить использовать queue.Queue , вам нужно найти обходные пути для этой проблемы.Обходные пути, однако, имеют свой собственный список недостатков и их сложнее поддерживать.Поиск другой очереди производитель-потребитель, которая предлагает функции, которые вам нужны, может быть лучшей идеей!В любом случае, есть два возможных обходных пути:
Опрос
while True:
try:
i1 = c1.get_nowait()
print "received %s from c1" % i1
except queue.Empty:
pass
try:
i2 = c2.get_nowait()
print "received %s from c2" % i2
except queue.Empty:
pass
time.sleep(0.1)
Это может использовать много циклов ЦП при опросе каналов и может быть медленным при наличиимного сообщений.Использование time.sleep () с экспоненциальным временем задержки (вместо показанных здесь постоянных 0,1 с) может значительно улучшить эту версию.
Одиночная очередь уведомлений
queue_id = notify.get()
if queue_id == 1:
i1 = c1.get()
print "received %s from c1" % i1
elif queue_id == 2:
i2 = c2.get()
print "received %s from c2" % i2
При такой настройке вы должны отправить что-то в очередь уведомлений после отправки на c1 или c2.Это может сработать для вас, если вам достаточно только одной такой очереди уведомлений (т. Е. У вас нет нескольких «выборок», каждый из которых блокирует свое подмножество ваших каналов).
В качестве альтернативы вы можетеТакже рассмотрите возможность использования Go.Goroutines и поддержка параллелизма Go намного мощнее, чем ограниченные возможности Python для потоков.