玩转Openstack之Nova中的协同并发(一)
前不久参加了个Opnstack的Meetup,其中有一个来自EasyStack的大大就Nova中的协同并发做了一番讲解,有所感触,本想当天就总结一下,但是由于前段时间工作上比较忙,加上为了履行诺言每天几更的来写设计模式系列性文章,故而拖到今天才写此次的总结。好吧,其实归根结底还是自己太懒了,趁着闲时在补新番小笼包之类的。废话就此打住,开始正文。
Python中协程的介绍
在此之前,先介绍下Python中的并发,在Python中,并发有三种,分别是:
- 进程:Python中一般使用multiprocessing/subprocess来实现
- 线程:threading/thread是Python中用来实现多线程的模块
- 协程(Coroutines):Python中用于处理协程的模块倒是比较多,有eventlet、Twisted、Tulip、asyncio
有关进程、协程、线程中的关系图如下所示(图来自EasyStack的大大):
想必大家对进程以及线程那是相当的熟悉了,所以就重点介绍下协程:协程源自 Simula 和 Modula-2 语言,但也有其他语言支持。协程更适合于用来实现彼此熟悉的程序组件,如合作式多任务,迭代器,无限列表和管道。 协程最初在1963年被提出。那么协程又有什么特点呢?
- 每个协程都有自己的私有stack以及局部变量。
- 线程我们都知道可以多个同时运行,也就是所谓的多线程,但是同一时间只有一个协程在运行,所以就无须对某些共享变量加锁。
- 由于协程比较轻量级,所以一个线程中可以有多个协程。
- 协程之间的执行顺序,完全由程序来控制。
- 其实协程也就仅仅是一种概念罢了,非操作系统可见,在多种语言中都有实现,一会详细介绍的eventlet就是在Python中实现的一种。
Eventlet的介绍
eventlet其实就是对greenlet的一个封装,对其进行简单的封装之后,就成了所谓的greenthread,greenlet是一个称为协程(coroutine)的东西。下面上一个greenlet的栗子来介绍一下greenlet:
from greenlet import greenlet def test1():
print 12
gr2.switch()
print 34 def test2():
print 56
gr1.switch()
print 78 gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
这个栗子的执行结果是:
aaarticlea/png;base64,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" alt="" />
也就是说在这里先定义了两个函数test1,test2以及两个协程gr1,gr2,最后一行g1.switch()跳转到 test1() ,它打印12,然后执行gr2.switch(),跳转到 test2() ,打印56,然后又执行了gr1.switch()跳转回 test1() ,打印34,然后 test1() 就结束,gr1死掉,回到父greenlet,不会再切换到test2,所以不会打印78。在上面的例子中main greenlet就是它们的父 greenlet。
eventlet是一个用来处理和网络相关的python库函数,而且可以通过协程来实现并发,在eventlet里,把“协程”叫做greenthread(绿色线程)。所谓并发,就是开启了多个greenthread,并且对这些greenthread进行管理,以实现非阻塞式的I/O。比如说用eventlet可以很方便的写一个性能很好的web服务器,或者是一个效率很高的网页爬虫,这都归功于eventlet的“绿色线程”,以及对“绿色线程”的管理机制。更让人不可思议的是,eventlet为了实现“绿色线程”,竟然对python的和网络相关的几个标准库函数进行了改写,并且可以以补丁(patch)的方式导入到程序中,因为python的库函数只支持普通的线程,而不支持协程,eventlet称之为“绿化”。Eventlet库在OpenStack服务中上镜率很高,尤其是在服务的多线程和WSGI Server并发处理请求的情况下。
主要API如下:
Greenthread 产⽣:
spawn(func, *args, **kwargs): 创建一个绿色线程去运行func这个函数,后面的参数是传递给这个函数的参数。返回值是一个eventlet.GreenThread对象,这个对象可以用来接受func函数运行的返回值。在绿色线程池还没有满的情况下,这个绿色线程一被创建就立刻被执行。其实,用这种方法去创建线程也是可以理解的,线程被创建出来,肯定是有一定的任务要去执行,这里直接把函数当作参数传递进去,去执行一定的任务,就好像标准库中的线程用run()方法去执行任务一样。
spawn_n(func, *args, **kwargs): 这个函数和spawn()类似,不同的就是它没有返回值,因而更加高效,这种特性,使它也有存在的价值。
spawn_after(seconds, func, *args, **kwargs): 这个函数和spawn()基本上一样,都有一样的返回值,不同的是它可以限定在什么时候执行这个绿色线程,即在seconds秒之后,启动这个绿色线程。
Greenthread 控制:
sleep(seconds=0):中止当前绿色线程,以允许其它绿色线程执行。
eventlet.GreenPool: 这是一个类,在这个类中用set集合来容纳所创建的绿色线程,并且可以指定容纳线程的最大数量(默认是1000个),它的内部是用Semaphore和Event这两个类来对池进行控制的,这样就构成了线程池,下面有一些重要的方法:
running():返回当前池中的绿色线程数
free():返回当前池中可容纳的绿色线程数
spawn():创建新的绿色线程
spawn_n():同上
今天就先介绍到这里,下次再继续介绍协同并发在Nova中的应用。
参考资料:
5.easystack演讲
PS:本博客欢迎转发,但请注明博客地址及作者,因本人水平有限,若有不对之处,欢迎指出,谢谢~
博客地址:http://www.cnblogs.com/voidy/
博客新址:http://voidy.net
<。)#)))≦