如何同步python列表?

时间:2012-06-19 07:50:56

标签: python multithreading

我有不同的线程,在处理后,他们将数据放在一个公共列表中。是否有任何内置在python中的列表或numpy数组只能由一个线程访问。其次,如果它不是一种优雅的方式吗?

3 个答案:

答案 0 :(得分:4)

如果您需要保护整个关键部分,

threading提供Lock个对象,或者Queue模块提供线程安全的队列。

答案 1 :(得分:4)

根据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数组,通常情况下,您需要的不仅仅是生产者/消费者队列,请使用Lock或来自threadingRLock - 这些实现了上下文管理器协议,所以使用它们非常简单:

with mylock:
    # Process as necessarry

并且python将保证一旦你从with块结束时锁定被释放 - 包括在棘手的情况下,比如你做的事情会引发异常。

最后,考虑multiprocessing是否更适合您的应用程序而不是threading - Python中的线程不能保证实际并发运行,而且只有在CPython中才能降低到C级别码。 multiprocessing解决了这个问题,但可能会有一些额外的开销 - 如果你还没有,你应该阅读文档以确定哪一个更适合你的需求。

答案 2 :(得分:1)

标准库Queue怎么样?