我只是在搜索这个新实现,我使用 python 2.7,我必须安装它,所以如果我使用它,我会忘记 CPython 上的 GIL 这个词吗?
1 回答
不,concurrent.futures
与 GIL 几乎没有任何关系。
使用进程而不是线程是 GIL 的良药。(当然,像所有药物一样,它有副作用。但它有效。)
该模块只是为您提供了一种比直接使用或futures
更简单的方法来安排和等待任务。它还有一个额外的优势,即您可以在线程池和进程池之间进行交换(甚至可能是一个 greenlet 循环,或者您发明和构建的一些疯狂的东西),而无需更改代码。所以,如果你不知道你的代码是否会出现 GIL 问题,你可以将它构建为使用线程,然后通过一行更改将其切换为使用进程,这非常好。threading
multiprocessing
future
但是,如果您使用ThreadPoolExecutor
,它将具有完全相同的 GIL 问题,就好像您使用threading
和手动创建线程池、任务队列等一样queue
。如果您使用ProcessPoolExecutor
,它将以与multiprocessing
手动使用相同的方式(并且具有相同的权衡)避免 GIL 问题。
PyPI 包只是concurrent.futures
从 3.2 到 2.x(和 3.0-3.1)的模块的简单反向移植。(它不会神奇地为您提供新的和改进的 3.2 GIL,或者更改进的 3.3 GIL,更不用说删除 GIL。)
我什至不应该提到 GIL 的变化,因为这似乎只是增加了混乱……但是现在,让我尝试通过过度简化来理顺它。
如果您只有 IO 绑定的工作,线程是获得并发性的好方法,达到合理的限制。并且 3.3 确实使它们工作得更好——但在大多数情况下,2.7 已经足够好,而对于大多数情况下,3.3 仍然不够好。如果您想同时处理 10000 个客户端,您将需要使用事件循环(例如 、、twisted
、tornado
等)而不是线程。gevent
tulip
如果您有任何 CPU 密集型工作,线程根本无助于并行化该工作。事实上,它们让事情变得更糟。3.3 让这个点球没有那么糟糕,但它仍然是一个点球,你仍然不应该这样做。如果要并行化 CPU 工作,则必须使用进程,而不是线程。3.3 的唯一优点是futures
比 更容易使用multiprocessing
,并且是内置的,无需安装。
我不想阻止您迁移到 3.3,因为它是比 2.7 更好的语言的更好实现。但更好的并发性并不是移动的理由。