Python 线程安全排序集合

Python 线程安全排序集合,python,collections,thread-safety,sorted,Python,Collections,Thread Safety,Sorted,Python中是否有线程安全排序集合的实现? 参考,但我不确定它是否线程安全(是吗?) 如果没有这样的实现,您将如何实现它?Python与Java不同:如果类没有在文档中指定其线程行为,则可以安全地假设它不是线程安全的 from heapq import heappush, heappop class Heap: def __init__(self): self._heap = [] def push(self, x): heappush(s

Python中是否有线程安全排序集合的实现?
参考,但我不确定它是否线程安全(是吗?)

如果没有这样的实现,您将如何实现它?

Python与Java不同:如果类没有在文档中指定其线程行为,则可以安全地假设它不是线程安全的

from heapq import heappush, heappop

class Heap:

    def __init__(self):
        self._heap = []

    def push(self, x):
        heappush(self._heap, x)

    def pop(self):
        return heappop(self.heap)
Python编写时没有考虑线程。即使在今天,多线程仍然是二等公民,因为只有一个线程始终处于活动状态(这并不能防止大多数数据争用问题)。它被称为全局解释器锁(GIL)


如果类或数据结构不是为并发而构建的,则必须通过查看代码来保护对它的访问,因为它似乎不是线程安全的。要从多个线程使用它,访问它的应用程序代码应该由信号量锁保护

如果要使SortedCollection类线程安全,可以编写一个decorator函数

它看起来像这样:

分类收集:

def __init__(self):
    self.mysemaphore = threading.Semaphore()

def guard(func):
    def guarded(*args, **kwds):
        self.mysemaphore.acquire()
        try:
            return func(*args, **kwds)
        finally:
            self.mysemaphore.release()

return guarded

# edit the class, applying the decorator to its methods.
@guard
def unsafeFunc(self, a, b, c):
    ''' do work here'''
编辑

不要错误地认为线程安全的数据结构会使应用程序代码线程安全。如果在一个SortedCollection上执行多个操作,则所有这些操作都需要由锁进行保护

即使SortedCollection是线程安全的,以下代码也不会:

slist.insert(1)
slist.insert(2)
另一个线程可能会在这两条语句之间插入一个项。您需要在应用程序代码中进行保护。如果将其添加到应用程序代码中,则无需将SortedCollection修改为线程安全的

semaphore2.acquire()

try:
    slist.insert(1)
    slist.insert(2)
finally:
    semaphore2.release()
collections.OrderedDict类对于更新不是线程安全的。您可以执行并发读取,但写入需要锁。有关如何将锁与OrderedICT一起使用的示例,请参阅源代码。

您可以使用该模块来维护排序列表。通过GIL的强大功能,所有对C扩展的调用都是原子的(在CPython中,除非扩展显式释放锁),因此
heappush
和friends是线程安全的

from heapq import heappush, heappop

class Heap:

    def __init__(self):
        self._heap = []

    def push(self, x):
        heappush(self._heap, x)

    def pop(self):
        return heappop(self.heap)

在python中,原子操作始终是线程安全的。仅当操作不是原子操作时才需要同步。GIL一次只允许一个原子操作,无论线程数如何。python中的多处理是另一回事

实际上,这与Java没有任何区别。在Java中,如果没有提到线程,那么可以安全地假设它不是线程安全的。尽管与python相反,您得到的是线程安全的集合—python在这方面非常缺乏:/func返回是否会阻止信号量的释放?@eduardocereto来自文档:
finally子句也会在try语句的任何其他子句通过中断离开时“在退出时”执行,continue或return语句。
为什么使用
线程。信号量
线程化。锁还不够吗?再说一遍,“线程安全”只是意味着来自多个线程的调用不能破坏数据结构的内部,来自不同线程的调用仍然可以按任意顺序执行。顺便说一句,在现代Python中,您是这样锁定的:
使用mylock:dostuff()
。使用全局
mysemaphore
,您不会错误地在
SortedCollection
的不同实例之间锁定吗?你怎么能对每个实例都这样做呢?实际上我不明白为什么Python没有内置这样一个类。。。。。。除了
heapq
不是C扩展
heapq
是用纯python实现的。退房快速查看,
heapq
看起来绝对不是线程安全的!我还应该补充一点,虽然
heapq
函数本身肯定不是线程安全的,但是您可以使用模块的,它是线程安全的,并且在内部使用
heapq