我想通过启动几个独立的异步操作线程来加快脚本的执行速度,否则这些操作会一个接一个地启动。
我使用了concurrent.future文档中的示例,并将其改编为我的代码:
import concurrent.futures
def myfunc(elem):
elem['ascii'] = ord(elem['name'])
mylist = [
{'name': 'a'},
{'name': 'b'},
{'name': 'c'},
{'name': 'd'},
{'name': 'e'}
]
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
future_to_url = {executor.submit(myfunc, elem): elem for elem in mylist}
for future in concurrent.futures.as_completed(future_to_url):
try:
future.result()
except Exception as exc:
print('error: '.format(exc))
print mylist
代码按预期工作,但我是否应该担心对mylist
的并发访问,或者是否正确锁定并以串行方式访问(或任何正确的方式,以便数据一致)?
在实际程序中,字典会大得多,我想启动~500个工人。
我想通过启动多个线程来加快脚本的执行速度
由于CPython的实现带来的挑战,如果您对性能感兴趣,则可能应该改用ProcessPoolExecutor
。 请注意,这将需要一个更复杂的设计,即工作人员如何与应共享的数据结构进行通信和/或交互。
现在,进入您的问题:
我应该担心对mylist的并发访问,或者IS是否正确锁定并以串行方式访问(或任何正确的方式,以便数据保持一致)
list
在多线程环境中将正常运行,但是如果顶部有任何需要原子性的语义分层,则需要自己的锁定。 例如,假设您的设计要求/期望list
应始终具有七个元素,并且一些工人会先做一个pop()
,然后做一个append()
。 您将需要自己的锁来保护工作线程免受它们之间的并发访问。