Наличие дек с преимуществами очереди в потоке - PullRequest
1 голос
/ 30 июня 2019

Мне нужна структура, в которой я смогу выполнять pop () и append () справа (точно так же, как deque), при этом структура блокируется и ждет, если она пуста (как очередь).Я мог бы напрямую использовать Очередь, но мне также нужна приятная особенность deque, при которой элементы удаляются без блокировки, если структура заполнена.

from collections import deque
d = deque(maxlen=2)
d.append(1)
d.append(2)
d.append(3) # d should be [2,3] (it is the case)
d.pop()
d.pop()
d.pop() # should wait (not the case)

Лучше ли создавать подкласс deque (заставляя его ждать) или Queue(добавив функцию popLeft)?

Ответы [ 2 ]

2 голосов
/ 30 июня 2019

Как насчет создания собственной очереди, смешивающей лучшее из обоих?

import queue as Queue
from collections import deque

class QueuePro:
  def __init__(self, maxlenDeque): 
    self.deque = deque(maxlen=maxlenDeque)
    self.queue = Queue.Queue()

  def append(self, elem):
    self.deque.append(elem)
    self.queue.put(elem)

  def pop(self):
    if(not self.deque):
      self.queue.get()
    else:
      self.deque.pop()
      self.queue.get()


q2 = QueuePro(2)
q2.append(1)
q2.append(2)

q2.pop()
q2.pop()
q2.pop()
#waiting
1 голос
/ 30 июня 2019

Не уверен, что лучше, но вот идея для добавления wait для pop с threading.Event

from collections import deque
from threading import Event

class MyDeque(deque):
    def __init__(self, max_length):
        super().__init__(maxlen=max_length)
        self.not_empty = Event()
        self.not_empty.set()

    def append(self, elem):
        super().append(elem)
        self.not_empty.set()

    def pop(self):
        self.not_empty.wait()  # Wait until not empty, or next append call
        if not (len(q) - 1):
            self.not_empty.clear()
        return super().pop()

q = MyDeque(2)
q.append(1)
q.append(2)
q.append(3)
q.pop()
q.pop()
q.pop()  # Waits 
...