我想通过启动几个独立的异步操作线程来加速脚本的执行,否则这些操作会一个接一个地启动。
我使用the example from concurrent.future docs并将其改编为我的代码:
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名工人。
答案 0 :(得分:0)
我想通过启动多个线程来加速脚本的执行
由于challenges posed by CPython's implementation,如果您对性能感兴趣,则应该使用ProcessPoolExecutor
。请注意,这将需要一个关于工作者如何与应该共享的数据结构进行通信和/或交互的设计。
现在,问你的问题:
我应该担心对mylist的并发访问,还是以串行的方式正确锁定和访问(或者任何正确的访问,以便数据保持一致)
list
将在多线程环境中正常运行,但如果您在顶部有任何需要原子性的语义分层,则需要您自己的锁定。例如,假设您的设计需要/期望list
应始终包含七个元素,而某些工作人员将执行pop()
后跟append()
。您将需要自己的锁来保护工作人员免受这些工作之间的并发访问。