Python 在不阻止追加的情况下线程安全地复制数据块

Python 在不阻止追加的情况下线程安全地复制数据块,python,multithreading,deque,Python,Multithreading,Deque,我试图用python创建一个循环缓冲区。 我最好的实现是使用固定长度的deque。 (基本实施) 我知道从两侧追加和删除元素是线程安全的,但我还需要能够复制N个元素。这就是我使用此互斥锁的原因。 问题是我不想在其他线程复制缓冲区中的数据时阻止新元素的插入。 有没有办法在没有互斥锁的情况下实现此行为?在CPython中,此副本是原子的(一旦开始运行): 列表构建、itertools切片和deque迭代都是用C实现的,没有纯python回调。此外,复制操作不会导致任何减量降至零,从而消除另一个非原子

我试图用python创建一个循环缓冲区。 我最好的实现是使用固定长度的
deque

(基本实施)

我知道从两侧追加和删除元素是线程安全的,但我还需要能够复制N个元素。这就是我使用此互斥锁的原因。
问题是我不想在其他线程复制缓冲区中的数据时阻止新元素的插入。

有没有办法在没有互斥锁的情况下实现此行为?在CPython中,此副本是原子的(一旦开始运行):


列表构建、itertools切片和deque迭代都是用C实现的,没有纯python回调。此外,复制操作不会导致任何减量降至零,从而消除另一个非原子行为源。

您是在询问无锁编程吗?这在Python中是非常复杂和毫无意义的(Python中至少有一个互斥体是不可避免的:GIL)。或者您希望读取器和插入器能够同时运行(换句话说,您希望使用短期互斥)?@freakish我不希望在复制缓冲区数据时阻止追加操作。例如:deque包含30个元素(整数从0到29),我想从右侧(9到29)复制20个元素。在这种情况下,我希望仍然能够将新元素从不同的线程推送到缓冲区,而不必等待mutexRight,因此这里的操作是CRUD(创建-读取-更新-删除),可能只有CRD。所以你现在的“锁定一切”策略是悲观的。还有其他一些,例如在PostgreSQL中实现的。无论如何,这是一个巨大的主题,这些算法并不容易。不要期望它通过一些魔术来实现这一点。很可能您也需要更改数据结构。
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
s = list(islice(some_deque, 20))