我一直在做一些阅读,但在Python 2.7中找不到我的问题的最佳实践,它就是这样:
我有一个项目列表,我想遍历所有项目并调用一些函数。此函数将对这些项执行一些操作并返回新项。 函数中的每个返回值都将附加到新的项列表中。 一切都很好,很简单,直到我尝试使用线程。
我想做同样的工作,但是现在每个函数调用都将打开一个新线程(最多20个线程)来执行函数的工作并返回所需的信息以附加到列表中。
newList = []
for item in myList:
info = getInfo(item)
newList.append(info)
return newList
从我读到的,列表是线程安全的,所以我想可能使用队列和线程模块然后将所有当前项目放入队列,在传递newList并在每个线程中追加时执行每个项目的工作... 有什么想法吗?
答案 0 :(得分:2)
最明智的做法是假设操作不是线程安全的,除非你毫无疑问地知道它们是。
确保任何操作的原子性的最简单方法是在执行操作之前获取锁定,并且仅在执行操作时释放锁定。现在with
语句非常简单,因为锁对象是上下文管理器。
假设您的列表是模块全局my_list
,那么这很容易完成,如下所示。
my_lock = threading.Lock()
my_list = []
:
:
:
def my_list_append(o):
with my_lock:
my_list.append(o)
另请注意,必须使用相同的锁进行列表的任何其他修改(例如,弹出一个项目)。通过在其他线程中建立索引来简单访问元素应该不是问题。
另一种可能的方法是让线程执行操作,并通过作为参数传递给线程的Queue.queue对象发送要附加到列表的项。这假设只有该线程会向列表添加任何内容。由于锁定解决方案非常简单,除非必须,否则我不会考虑这个问题。