Python的更简单的并发构建块?
看起来Python的标准库里缺少一些有用的并发相关的概念,比如原子计数器、执行器等等,这些在Java的java.util.concurrent里都有。有没有什么外部库可以提供更简单的构建模块,帮助我们更容易地开发并发的Python应用呢?
5 个回答
在Python(至少是CPython版本)和Java之间,处理并发的方式差别很大,部分原因是有个叫做全局解释器锁(GIL)的东西。一般来说,Python中的并发不是通过线程来实现的,而是通过进程。你可以查看multiprocessing
模块,它是处理并发的“标准”模块。
另外,可以看看“关于协程和并发的有趣课程”,里面有一些并发的技巧,对于我这个从Java过来的来说,感觉挺新鲜的。David Beazley(作者)在Python方面非常聪明,尤其是在并发处理上。
虽然这可能一开始不太明显,但itertools.count 确实是一个原子计数器(对一个实例 x
来说,唯一的操作 next(x)
相当于 C 语言中的“原子 ++x
”,如果 C 有这样的概念的话;-)。补充:至少在 CPython 中是这样;我原以为这是 Python 标准的一部分,但显然 IronPython 和 Jython 在当前实现中不同意这一点(没有确保 count.next 的线程安全),所以我可能是错的!
也就是说,假设你现在有一个数据结构,比如:
counters = dict.fromkeys(words_of_interest, 0)
...
if w in counters: counters[w] += 1
而你的问题是,后面的递增操作不是原子的,所以如果两个线程同时处理同一个感兴趣的字,两个递增可能会互相干扰(只有一个会“生效”,所以计数器只会增加一次,而不是两次)。那么:
counters = dict((w, itertools.count()) for w in words_of_interest)
...
if w in counters: next(counters[w])
将以原子的方式执行相同的操作。
(不幸的是,目前没有明显的、文档化的方法来“提取计数器的当前值”,不过实际上 str(x)
会返回一个字符串,比如 'count(3)'
,从中可以解析出当前值;-)。
Kamaelia,正如之前提到的,旨在让在Python中处理并发变得更简单。
它最初的应用场景是网络系统(这类系统本身就是并发的),开发时的想法是“我们如何能让这些系统更容易开发和维护”。
随着时间的推移,它的应用范围变得更广泛,从桌面系统(比如白板应用、数据库建模、教孩子读写的工具)到网站的后端系统(比如转码和转换用户上传的图片和视频,以便在各种场景下进行网络播放,以及短信/文本消息应用)。
它的核心概念基本上和Unix的管道类似——不过这里用的不是进程,而是Python生成器、线程或进程,这些被称为组件。组件之间通过收件箱和发件箱进行通信——你可以有任意数量的收件箱和发件箱,而不仅仅是标准输入/输出/错误输出。此外,不需要使用序列化的文件接口,你可以在组件之间传递完整的Python对象。而且,不仅限于管道,你还可以有任意形状的连接,这被称为图形线。
你可以在这里找到完整的教程(视频、幻灯片、可下载的PDF手册):
或者在这里找到5分钟的简版(O'Reilly的快速演讲):
这个库的重点是实用开发、系统安全和易于维护,尽管最近也花了一些精力在增加一些语法糖上。像任何东西一样,开发者(我和其他人 :-) 欢迎反馈以改进它。
你还可以在这里找到更多信息: - http://www.slideshare.net/kamaelian
Kamaelia的核心(Axon)最初是为了让我的日常工作更轻松,并将最佳实践(消息传递、软件事务内存)以可重用的方式封装起来。我希望它也能让你的生活更轻松 :-)