Python中如何实现阻塞双端队列

2023-04-11 00:00:00 队列 阻塞 如何实现

Python中可以利用Queue模块实现阻塞双端队列。Queue模块提供了线程安全的队列,包括FIFO队列(先进先出)和LIFO队列(Last In,First Out)。在这里我们使用deque双端队列来实现阻塞队列,deque是一个双端队列,可以在两端进行操作。

代码如下:

import threading
from collections import deque

class BlockingDeque:
    def __init__(self, max_len=10):
        self.max_len = max_len
        self.deque = deque()
        self.lock = threading.Lock()
        self.condition = threading.Condition(self.lock)

    def append(self, item):
        with self.lock:
            while len(self.deque) >= self.max_len:
                self.condition.wait()
            self.deque.append(item)
            self.condition.notify_all()

    def appendleft(self, item):
        with self.lock:
            while len(self.deque) >= self.max_len:
                self.condition.wait()
            self.deque.appendleft(item)
            self.condition.notify_all()

    def pop(self):
        with self.lock:
            while len(self.deque) == 0:
                self.condition.wait()
            item = self.deque.pop()
            self.condition.notify_all()
            return item

    def popleft(self):
        with self.lock:
            while len(self.deque) == 0:
                self.condition.wait()
            item = self.deque.popleft()
            self.condition.notify_all()
            return item

这个类实现了一个双端队列。当队列满时,append和appendleft操作会阻塞,直到队列中元素被取出。当队列为空时,pop和popleft操作会阻塞,直到队列中有元素。

接下来我们演示一下如何使用这个类:

bd = BlockingDeque(max_len=5)

def producer():
    for i in range(10):
        bd.append('pidancode.com')
        print('append item: {}'.format('pidancode.com'))

def consumer():
    for i in range(10):
        item = bd.pop()
        print('pop item: {}'.format(item))

t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)
t1.start()
t2.start()
t1.join()
t2.join()

这里我们开启了两个线程,一个生产者线程,一个消费者线程。生产者线程向队列中添加元素,消费者线程从队列中取出元素。由于队列是阻塞队列,当队列中元素满或为空时,线程会被阻塞,直到队列中有足够的元素或者元素被取出。

相关文章