這篇文章主要介紹了簡單介紹Python中利用生成器實現的並發編程,使用yield生成器函數進行多進程編程是Python學習進階當中的重要知識,需要的朋友可以參考下
我們都知道並發(不是並行)編程目前有四種方式,多進程,多線程,異步,和協程。
多進程編程在python中有類似C的os.fork,當然還有更高層封裝的multiprocessing標准庫,在之前寫過的python高可用程序設計方法中提供了類似nginx中master process和worker process間信號處理的方式,保證了業務進程的退出可以被主進程感知。
多線程編程python中有Thread和threading,在linux下所謂的線程,實際上是LWP輕量級進程,其在內核中具有和進程相同的調度方式,有關LWP,COW(寫時拷貝),fork,vfork,clone等的資料較多,這裡不再贅述。
異步在linux下主要有三種實現select,poll,epoll,關於異步不是本文的重點。
說協程肯定要說yield,我們先來看一個例子:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #coding=utf-8 import time import sys # 生產者 def produce(l): i=0 while 1: if i < 5: l.append(i) yield i i=i+1 time.sleep(1) else: return # 消費者 def consume(l): p = produce(l) while 1: try: p.next() while len(l) > 0: print l.pop() except StopIteration: sys.exit(0) l = [] consume(l)在上面的例子中,當程序執行到produce的yield i時,返回了一個generator,當我們在custom中調用p.next(),程序又返回到produce的yield i繼續執行,這樣l中又append了元素,然後我們print l.pop(),直到p.next()引發了StopIteration異常。
通過上面的例子我們看到協程的調度對於內核來說是不可見的,協程間是協同調度的,這使得並發量在上萬的時候,協程的性能是遠高於線程的。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import stackless import urllib2 def output(): while 1: url=chan.receive() print url f=urllib2.urlopen(url) #print f.read() print stackless.getcurrent() def input(): f=open('url.txt') l=f.readlines() for i in l: chan.send(i) chan=stackless.channel() [stackless.tasklet(output)() for i in xrange(10)] stackless.tasklet(input)() stackless.run()關於協程,可以參考greenlet,stackless,gevent,eventlet等的實現。