我有不同的线程,处理后它们将数据放在一个公共(public)列表中。是否有任何内置于 python 中的列表或 numpy 数组只能由单个线程访问。其次,如果不是,那么优雅的做法是什么?
最佳答案
根据 Thread synchronisation mechanisms in Python ,从列表中读取单个项目并就地修改列表保证是原子的。如果这是正确的(尽管它似乎与 Queue 模块的存在部分矛盾),那么如果您的代码全部为以下形式:
try:
val = mylist.pop()
except IndexError:
# wait for a while or exit
else:
# process val
而放入mylist
的所有内容都是由.append()
完成的,那么你的代码就已经是线程安全的了。如果您不信任该分数上的那个文档,请使用 queue.queue ,它为您完成所有同步,并且具有比 list
更好的 API 用于并发程序 - 特别是,它为您提供了无限期阻塞或超时等待 .pop( )
如果您没有任何线程可以同时处理的其他内容,则可以工作。
对于 numpy 数组,通常在任何情况下您需要的不仅仅是生产者/消费者队列,请使用 threading
中的 Lock
或 RLock
- 这些实现了上下文管理器协议(protocol),因此使用它们非常简单:
with mylock:
# Process as necessarry
并且 python 将保证一旦你从 with
block 的末尾掉下来就释放锁 - 包括在棘手的情况下,比如你做的事情引发了异常。
最后,考虑是否multiprocessing
比 threading
更适合您的应用程序 - Python 中的线程不能保证实际上并发运行,而在 CPython 中只有下降到 C 级代码时才能保证。 multiprocessing
解决了这个问题,但可能会有一些额外的开销 - 如果您还没有阅读文档,您应该阅读文档以确定哪个更适合您的需求。
关于python - 如何同步python列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11096634/