【问题标题】:Is there non-synchronized queue in pythonpython中是否有非同步队列
【发布时间】:2023-03-13 12:08:01
【问题描述】:

我正在练习使用 python(实际上是 pypy3)进行编程比赛。对于一个问题,我需要使用一个队列——我只需要放在一端并从另一端弹出。从我在文档中找到的内容看来,我有两个选项queue.Queuequeue.deque。我首先使用 queue.Queue 尝试了该问题,但我的解决方案超出了时间限制。然后我切换到queue.deque,我通过了问题(虽然接近极限)。

从文档看来,这两个容器都是线程安全的(至少对于双端队列的某些操作而言),而对于我的情况,我永远不会使用多个线程。 python中是否内置了一个简单的非同步队列?

【问题讨论】:

  • 你试过collections.deque吗?
  • @PM2Ring 看来这个容器也同步了:Deques support thread-safe, memory efficient appends and pops from either side of the deque with approximately the same O(1) performance in either direction.
  • @PM2Ring 我明白了,所以操作不需要锁定。因此,这种结构似乎可以解决问题。您链接到的问题不会将 colllection.deque 与 queue.deque 进行比较。他们如何比较?有什么区别?
  • queue.Queue(在 Python 2 中也称为 Queue.Queue)在内部使用 collections.deque;如果您不需要 queue.Queue 的特殊功能,您应该使用普通的 collections.deque

标签: python python-3.x queue


【解决方案1】:

deque当然不做同步;文档只是说明附加和弹出保证是线程安全的,因为它们是原子的。特别是在 CPython 中,除了 Global Interpreter Lock 之外没有锁定。如果您需要 double-ended queue,或者说 FIFO,那就是您应该使用的。如果您需要 LIFO 堆栈,请使用列表。在内部,deque 实现使用doubly-linked list of fixed-length blocks

queue.Queue 在内部使用deque;此外,它使用互斥锁来保护那些未被deque原子实现的剩余操作。

因此,您的问题不在于deque 的选择,而很可能是您算法的其他方面。

【讨论】:

    【解决方案2】:

    您可以使用两个普通列表(作为堆栈)来模拟一个队列。

    class Queue:
        def __init__(self):
            self.l1 = []   # Add new items here
            self.l2 = []   # Remove items here
    
        # O(1) time - simple stack push
        def enqueue(self, x):
            self.l1.append(x)
    
        # O(1) when l2 is not empty
        # O(k) if l2 is empty, but k is bounded by the number
        # of preceding calls to enqueue. Abusing the notation a bit,
        # you can think of the average for each call in a series to be
        # (k*O(1) + O(k))/k = O(1)
        def dequeue():
            if not self.l2:
                self.l2 = self.l1[::-1] #  Copy and reverse
                self.l1 = []
            return self.l2.pop()
    

    【讨论】:

    • collections.deque 存在时没有理由使用它; (另外,这是一个非线程安全的双端队列示例)
    • 该问题明确指出线程安全不是问题。这只是为了指出实现队列相当简单。
    猜你喜欢
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2021-10-28
    相关资源
    最近更新 更多