好久沒更新博客了。正好最近要整理一下最近這段時間做過的項目以及學習python的一些心得。如標題所示,今天就來說說windows下多進程加協程並發模式。其實網上還是蠻多在linux下的多進程加協程並發模式,本身linux對python的支持更好吧。但是由於本人的開發環境是windows的,而且網上關於這方面的資料還是少了一點,不過經過一番折騰,也算是弄出來了。廢話不多說,先貼代碼吧:
# coding=utf-8 # windows下多進程加協程並發模式 # 打入gevent的monkey補丁 from gevent import monkey monkey.patch_all() # 導入協程池 from gevent.pool import Pool import urllib2 # 導入多進程模塊 import multiprocessing import time # 定義一個爬取微博網頁的方法 def html(url=u'http://weibo.com/'): # 用上多進程的鎖機制,用於防止連續打印 lock = multiprocessing.Lock() try: h = urllib2.urlopen(url).read() except: lock.acquire() print u'連接錯誤' lock.release() else: lock.acquire() print u'done' lock.release() # 定義一個協程並發方法(用的是gevent的協程池) def a(num): pool = Pool(100) # 協程池的map方法可以讓你自定義並發次數,這里可以自定義爬取微博網頁的並發次數,第一個參數是要執行的函數 # 第二個參數可以理解成需要並發參數的次數 pool.map(html, [u'http://weibo.com/' for i in xrange(num)]) pool.kill() pool.join() # 這個是比較關鍵的一個方法,就是協程加多進程的並發模式 def b(num): t = [] # 建立10個進程來並行協程即方法a for i in xrange(10): p = multiprocessing.Process(target=a, args=(num,)) p.start() t.append(p) for each in t: each.join() # 對比多進程加協程與純粹協程的各自的並發狀態 if __name__ == '__main__': print u'方法b開始計時:' start = time.time() b(10) print u'方法b總共花費%f秒' % (time.time() - start) print u'方法a開始計時:' start = time.time() a(100) print u'方法a總共花費%f秒' % (time.time() - start)
上面的代碼注釋的挺清楚的了,下面貼一下執行的結果吧:
從上面的結果可以看到,執行協程加多進程的方法b時,多核cpu是可以被充分利用的,這是單純使用協程方式無法做到的,這也是多進程的一大好處吧。由於我這里實驗的是100次並發,所以其實就效果來說還不是很明顯,但是當你要瞬時並發一千個或者一萬個的時候,差距就可以顯現出來了,顯然,協程加多進程的方式是更加牛叉的,這種模式充分把兩者的優點結合起來了。
這里如果讀者對python的協程模塊與多進程模塊不熟悉的話,還是自行百度一下吧。畢竟自己真正理解了才是自己的東西啊。其實我也還是個python菜鳥,如果上面的代碼有啥問題或者更好的建議的話,還希望大神們不吝賜教呀!