线程安全的排序集合
Python 中有线程安全排序集合的实现吗?
Python 文档参考 SortedCollection 但我不确定它是否是线程安全的(是吗?)
如果没有这样的实施——你将如何实施它?
Is there an implementation of a thread-safe sorted collection in Python?
Python's docs reference SortedCollection but I'm not sure if it's thread-safe (is it?)
If there is no such implementation - how would you implement it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
仔细看代码,似乎不是线程安全的。要从多个线程使用它,访问它的应用程序代码应该使用信号量锁进行保护。
如果你想让 SortedCollection 类线程安全,你可以编写一个装饰器函数。
它看起来像这样:
SortedCollection:
编辑
不要错误地认为线程安全数据结构将使您的应用程序代码线程安全。如果对 SortedCollection 执行多个操作,则所有这些操作都需要由锁保护。
即使 SortedCollection 是线程安全的,以下代码也不会是线程安全的:
另一个线程可能会在这两个语句之间插入一个项目。您需要保护您的应用程序代码。如果将其添加到应用程序代码中,则无需将 SortedCollection 修改为线程安全的。
Looking through the code, it does not appear to be thread safe. To use it from multiple threads the application code that accesses it should be guarded with semaphore locks.
If you want to make the SortedCollection class thread safe, you could write a decorator function.
It would look something like this:
SortedCollection:
EDIT
Don't make the mistake of thinking that a threadsafe data structure will make your application code thread safe. If you perform multiple operations on a SortedCollection, all of those operations need to be guarded by a lock.
Even if SortedCollection is threadsafe, the following code would not be:
It is possible that another thread could insert an item in between those 2 statements. You will need to guard within your application code. If you add this to your application code, you will not need to modify the SortedCollection to be thread safe.
collections.OrderedDict 类对于更新来说不是线程安全的。您可以进行并发读取,但写入需要锁。有关如何将锁与 OrderedDict 一起使用的示例,请参阅 functools.lru_cache()。
The collections.OrderedDict class is not threadsafe for updates. You can do concurrent reads, but locks are needed for writes. For an example of how to use locks with OrderedDict, see the source for functools.lru_cache().
Python 与 Java 不同:如果一个类没有在文档中指定其线程行为,则可以安全地假设它不是线程安全的。
Python 编写时并没有考虑到线程。即使在今天,多线程实际上仍然是二等公民,因为只有一个线程始终处于活动状态(这并不能防止大多数数据竞争问题)。它称为全局解释器锁(GIL)。
如果类或数据结构不是为并发而构建的,则必须通过 外部锁
Python is different from Java: If a class has not specified its threading behavior in the docs, it is safe to assume that it is not thread-safe.
Python is not written with threading in mind. Even today, multi threading is really a second class citizen as only a single thread is active at all times (which does not prevent most data race issues). It is called Global Interpreter Lock (GIL).
If a class or a data structure is not build for concurrency, you have to protect access to it by an external lock
您可以使用 heapq 模块来维护排序列表。借助 GIL 的力量,对 C 扩展的所有调用都是原子的(在 CPython 中,除非扩展显式释放锁),因此 heappush 和朋友是线程安全的。
You can use the heapq module to maintain a sorted list. By the power of the GIL all calls to C Extensions are atomic (in CPython, unless the extension explicitly releases the lock) and therefore
heappush
and friends are thread-safe.Python 中的原子操作始终是线程安全的。仅当操作不是原子操作时才需要同步。无论线程数量有多少,GIL 一次只允许一个原子操作。 python 中的多重处理是另一回事。
Atomic operations are always thread-safe in python. You only need to synchronize if the operations are not atomic. The GIL only ever allows one atomic operation at a time, no matter the number of threads. Multi-processing in python is another matter.