我应该担心并发访问多线程 python 脚本中的 dict 吗?

WoJ*_*WoJ 5 python concurrency multithreading dictionary

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

我使用了 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
Run Code Online (Sandbox Code Playgroud)

该代码按预期工作,但我mylist是否应该担心并发访问或是否以串行方式正确锁定和访问(或任何正确的方式以使数据一致)?

在实际程序中,字典会更大,我想启动约 500 名工人。

Bri*_*ain 0

我想通过启动多个线程来加快脚本的执行速度

由于CPython 的实现带来了挑战ProcessPoolExecutor,如果您对性能感兴趣,您可能应该使用。请注意,这需要在工作人员如何与应共享的数据结构进行通信和/或交互方面更加复杂的设计。

现在,回答你的问题:

我是否应该担心对 mylist 的并发访问,或者是否正确锁定并以串行方式访问(或任何正确的方式以使数据一致)

它将在多线程list环境中正常运行,但如果您有任何需要原子性的语义分层,则您将需要自己的锁定。举例来说,您的设计要求/期望 应该始终具有七个元素,并且一些工作人员会执行 a后接一个。您将需要自己的锁来保护工作人员免受这些工作人员之间的并发访问。listpop()append()