concurrent.futures是GIL的解药吗?

14

我刚刚在搜索这个新实现时发现,我使用的是Python 2.7,我必须安装这个,那么如果我使用它,我会忘记在CPython中的GIL吗?


1
http://www.dalkescientific.com/writings/diary/archive/2012/01/19/concurrent.futures.html - Robert Harvey
1
http://docs.python.org/dev/library/concurrent.futures.html#module-concurrent.futures -- 没有提到GIL,因此它使用的线程显然是真正的线程。否则,为什么要费这么大劲呢? - Robert Harvey
我发现异步代码喜欢使用concurrent.futures,所以我说它是GIL的良药。 - Abdelouahab Pp
1
@RobertHarvey:您总是可以构建一个适合future API的GreenThreadExecutor。(然而,这证明有点棘手,这就是为什么tulip将为其协程事件循环带来略微不同的future以供stdlib使用。) - abarnert
1个回答

36
不,concurrent.futures 几乎与全局解释器锁(GIL)无关。
使用进程而不是线程是针对GIL的药物。(当然,像所有药物一样,它会有副作用。但它有效。) futures 模块只是提供了比直接使用 threadingmultiprocessing 更简单的任务调度和等待方式。它还具有一个优点,你可以在不改变 future 代码的情况下在线程池和进程池之间切换(甚至可能是绿色线程循环,或者是你发明和构建的某些奇怪东西),这非常好。因此,如果你不知道你的代码是否会有GIL问题,你可以构建一个使用线程的代码,然后通过一行代码切换到使用进程,这相当不错。
但是,如果你使用 ThreadPoolExecutor,它将有与手动使用 threadingqueue 创建线程池、任务队列等完全相同的 GIL 问题。如果你使用 ProcessPoolExecutor,它将以与手动使用 multiprocessing 相同的方式避免GIL问题(并具有相同的权衡)。
PyPI软件包只是将 concurrent.futures 模块从3.2回退到2.x (和3.0-3.1)的简单后移。它并不会自动给你提供新的,有点改进的3.2 GIL,或者更大的改进的 3.3 GIL,更不用说消除GIL问题了。
我可能甚至不应该提到GIL的变化,因为这似乎只是增加了混乱…但现在,让我试着用过于简单化的方式来澄清。如果你所需的全部工作都是I/O绑定的,那么线程是实现并发性的好方法,但只能达到一个合理的限制。3.3版本使它们更加有效,但对于大多数情况而言,2.7已经足够好了。如果您想要处理10000个同时客户端,那么您将需要使用事件循环(例如twistedtornadogeventtulip等),而不是线程。
如果您有任何CPU绑定的工作,线程根本无法帮助并行化该工作。实际上,它们会使事情变得更糟。 3.3版本减轻了这种惩罚,但仍然存在,因此您永远不应该这样做。如果要并行处理CPU工作,则必须使用进程,而不是线程。唯一的优点是3.3中的futuresmultiprocessing更易于使用,并且已内置,而不需要安装它。
我不想阻止您转向3.3,因为它是一个比2.7更好的语言实现。但更好的并发性不是转移的理由。

2
@AbdelouahabPp:不,concurrent.futures除了让编写并发代码稍微简单一些之外,并没有解决任何问题。在3.2和3.3中对GIL的更改是完全独立的,这只是一个巧合,十多年来首次重大的GIL更改恰好出现在Python的同一版本中,即futures库。 - abarnert
2
@AbdelouahabPp:还没有。我的意思是,是的,你应该切换到3.3版本。但不是为了获得出色的并发代码。让我更新答案。 - abarnert
1
@AbdelouahabPp:首先,passlib已经转向3.x。来自https://pypi.python.org/pypi/passlib的消息:“Passlib是适用于Python 2和3的密码哈希库。”我刚刚执行了pip-3.3 install passlib,它正常工作。其次,在2.7上进行多进程处理的方式与3.3几乎完全相同。multiprocessing模块在2.7和3.3之间几乎是相同的,而PyPI futures回溯与3.3标准库中的concurrent.futures几乎相同。 - abarnert
1
@AbdelouahabPp:我不明白你的意思。如果你一直使用2.7版本,直到passlib适用于3.3版本,那么你不需要等待。它已经适用于3.3版本了。 - abarnert
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接