Python 线程安全排序集合
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与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
。