【发布时间】:2019-11-01 06:10:24
【问题描述】:
我正在尝试在 python 中创建一个循环缓冲区。
我最好的实现是使用固定长度的deque。
(基本实现)
class RingBuffer(object):
def __init__(self, size):
self.mutex = Lock()
self.deque = collections.deque(maxlen=size)
def push_elem(self, element):
copy.deepcopy(element)
with self.mutex:
self.deque.append(element)
def get_data(self, event, callback=None):
with self.mutex:
return copy.deepcopy(list(self.deque))
def get_elem(self):
if self.deque:
with self.mutex:
return cp.deepcopy(self.deque[-1])
return None
我知道从两侧追加和删除元素是线程安全的,但我还需要能够复制 N 个元素。这就是我使用这个互斥锁的原因。
问题是我不想在其他线程复制缓冲区中的数据时阻止新元素的插入。
有没有办法在没有互斥锁的情况下实现这种行为?
【问题讨论】:
-
你问的是无锁编程吗?无论如何,这在 Python 中非常复杂且毫无意义(Python 中至少有一个互斥锁是不可避免的:GIL)。或者您是否希望读取器和插入器能够同时运行(换句话说,您想要短暂的互斥锁)?
-
@freakish 我不想在复制缓冲区数据时阻止附加操作。例如:双端队列包含 30 个元素(从 0 到 29 的整数)我想从右边复制 20 个(9 到 29)。虽然发生这种情况,但我希望仍然能够将新元素从不同的线程推送到缓冲区,而无需等待互斥体
-
对,所以你这里的操作是CRUD(创建读取更新删除),可能只有CRD。所以你现在的“锁定一切”策略是一个悲观的concurrency control method。还有其他的,例如MVCC 在 PostgreSQL 中实现。无论如何,这是一个巨大的话题,这些算法并不容易。不要指望它会通过一些魔术来实现这一点。您很可能还需要更改数据结构。
标签: python multithreading deque