我应该担心多线程 Python 脚本中对字典的并发访问吗?



我想通过启动几个独立的异步操作线程来加快脚本的执行速度,否则这些操作会一个接一个地启动。

我使用了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()。 您将需要自己的锁来保护工作线程免受它们之间的并发访问。

最新更新