




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、玩轉(zhuǎn)Openstack之Nova中的協(xié)同并發(fā)前不久參加了個Opnstack的Meetup,其中有一個來自EasyStack的大大就Nova中的協(xié)同并發(fā)做了一番講解,有所感觸,本想當天就總結(jié)一下,但是由于前段時間工作上比較忙,加上為了履行諾言每天幾更的來寫設(shè)計模式系列性文章,故而拖到今天才寫此次的總結(jié)。好吧,其實歸根結(jié)底還是自己太懶了,趁著閑時在補新番小籠包之類的。廢話就此打住,開始正文。Python中協(xié)程的介紹在此之前,先介紹下Python中的并發(fā),在Python中,并發(fā)有三種,分別是:進程:Python中一般使用multiprocessing/subprocess來實現(xiàn)線程:threadin
2、g/thread是Python中用來實現(xiàn)多線程的模塊協(xié)程(Coroutines):Python中用于處理協(xié)程的模塊倒是比較多,有eventlet、Twisted、Tulip、asyncio有關(guān)進程、協(xié)程、線程中的關(guān)系圖如下所示(圖來自EasyStack的大大):想必大家對進程以及線程那是相當?shù)氖煜ち?,所以就重點介紹下協(xié)程:協(xié)程源自 Simula 和 Modula-2 語言,但也有其他語言支持。協(xié)程更適合于用來實現(xiàn)彼此熟悉的程序組件,如合作式多任務(wù),迭代器,無限列表和管道。 協(xié)程最初在1963年被提出。那么協(xié)程又有什么特點呢?每個協(xié)程都有自己的私有stack以及局部變量。線程我們都知道可以多個同
3、時運行,也就是所謂的多線程,但是同一時間只有一個協(xié)程在運行,所以就無須對某些共享變量加鎖。由于協(xié)程比較輕量級,所以一個線程中可以有多個協(xié)程。協(xié)程之間的執(zhí)行順序,完全由程序來控制。其實協(xié)程也就僅僅是一種概念罷了,非操作系統(tǒng)可見,在多種語言中都有實現(xiàn),一會詳細介紹的eventlet就是在Python中實現(xiàn)的一種。Eventlet的介紹eventlet其實就是對greenlet的一個封裝,對其進行簡單的封裝之后,就成了所謂的greenthread,greenlet是一個稱為協(xié)程(coroutine)的東西。下面上一個greenlet的例子來介紹一下greenlet:1from greenl
4、etimportgreenlet23def test1:4print 125gr2.switch6print 3478def test2:9print 5610gr1.switch11print 781213gr1 =greenlet(test1)14gr2 =greenlet(test2)15gr1.switch 執(zhí)行結(jié)果是:也就是說在這里先定義了兩個函數(shù)test1,test2以及兩個協(xié)程gr1,gr2,最后一行g(shù)1.switch跳轉(zhuǎn)到 test1 ,它打印12,然后執(zhí)行g(shù)r2.switch,跳轉(zhuǎn)到 t
5、est2 ,打印56,然后又執(zhí)行了gr1.switch跳轉(zhuǎn)回 test1 ,打印34,然后 test1 就結(jié)束,gr1死掉,回到父greenlet,不會再切換到test2,所以不會打印78。在上面的例子中main greenlet就是它們的父 greenlet。eventlet是一個用來處理和網(wǎng)絡(luò)相關(guān)的python庫函數(shù),而且可以通過協(xié)程來實現(xiàn)并發(fā),在eventlet里,把“協(xié)程”叫做greenthread(綠色線程)。所謂并發(fā),就是開啟了多個greenthread,并且對這些greenthread進行管理,以實現(xiàn)非阻塞式的I/O。比如說用eventlet可以很方便的寫一個性能很好的web服務(wù)
6、器,或者是一個效率很高的網(wǎng)頁爬蟲,這都歸功于eventlet的“綠色線程”,以及對“綠色線程”的管理機制。更讓人不可思議的是,eventlet為了實現(xiàn)“綠色線程”,竟然對python的和網(wǎng)絡(luò)相關(guān)的幾個標準庫函數(shù)進行了改寫,并且可以以補丁(patch)的方式導(dǎo)入到程序中,因為python的庫函數(shù)只支持普通的線程,而不支持協(xié)程,eventlet稱之為“綠化”。Eventlet庫在OpenStack服務(wù)中上鏡率很高,尤其是在服務(wù)的多線程和WSGI Server并發(fā)處理請求的情況下。主要API如下:Greenthread 產(chǎn):spawn(func, *args, *kwargs): 創(chuàng)建一個綠色線程去
7、運行func這個函數(shù),后面的參數(shù)是傳遞給這個函數(shù)的參數(shù)。返回值是一個eventlet.GreenThread對象,這個對象可以用來接受func函數(shù)運行的返回值。在綠色線程池還沒有滿的情況下,這個綠色線程一被創(chuàng)建就立刻被執(zhí)行。其實,用這種方法去創(chuàng)建線程也是可以理解的,線程被創(chuàng)建出來,肯定是有一定的任務(wù)要去執(zhí)行,這里直接把函數(shù)當作參數(shù)傳遞進去,去執(zhí)行一定的任務(wù),就好像標準庫中的線程用run方法去執(zhí)行任務(wù)一樣。spawn_n(func, *args, *kwargs): 這個函數(shù)和spawn類似,不同的就是它沒有返回值,因而更加高效,這種特性,使它也有存在的價值。spawn_after(second
8、s, func, *args, *kwargs): 這個函數(shù)和spawn基本上一樣,都有一樣的返回值,不同的是它可以限定在什么時候執(zhí)行這個綠色線程,即在seconds秒之后,啟動這個綠色線程。Greenthread 控制:sleep(seconds=0):中止當前綠色線程,以允許其它綠色線程執(zhí)行。eventlet.GreenPool: 這是一個類,在這個類中用set集合來容納所創(chuàng)建的綠色線程,并且可以指定容納線程的最大數(shù)量(默認是1000個),它的內(nèi)部是用Semaphore和Event這兩個類來對池進行控制的,這樣就構(gòu)成了線程池,下面有一些重要的方法:running:返回當前池中的綠色線程數(shù)
9、free:返回當前池中可容納的綠色線程數(shù) spawn:創(chuàng)建新的綠色線程 spawn_n:同上 接著談?wù)凮penstack中Nova對其的應(yīng)用。eventlet在nova/cmd/_init_.py中,就直接調(diào)用了eventlet的方法,代碼如下:from nova import debugger if debugger.enabled(): eventlet.monkey_patch(os=False, thread=False) else: eventlet.monkey_pat
10、ch(os=False) 這里在調(diào)試器被啟動后,關(guān)閉線程,然后啟用遠程調(diào)試器。這個就是eventlet.monkey_patch()的方法。這里僅僅是因為dnspython無法支持IPV6,所以使用eventlet的monkeypatch檢測一下環(huán)境變量的設(shè)置是否符合。greenthread在虛機遷移過程中如果看過我寫的源碼分析,相信對于下面的代碼不會陌生: greenthread.spawn(self._live_migration, context, instance, dest, post_method,
11、;recover_method, block_migration, migrate_data) 這個是熱遷移中所使用的所調(diào)用的由eventlet所封裝而成的綠色線程,調(diào)用了spawn(func,*args, kwargs)的函數(shù),創(chuàng)建了一個綠色線程去運行l(wèi)ive_migration也就是熱遷移的函數(shù),返回值是一個eventlet.greenthread的對象,這個對象可以用來接受live_migration運行的返回值。在綠色線程池未滿的情況下,就可以直接執(zhí)行熱遷移的函數(shù)。greenthread.sleep然后Nova中用到的最多的綠色線程的栗子可能就是time.
12、sleep了吧,下面隨便找了幾個用到的例子:for cnt in range(max_retry): try: self.plug_vifs(instance, network_info) break except processutils.ProcessExecutionError: if cnt = max_retry - 1: raise else:
13、 LOG.warn(_('plug_vifs() failed %(cnt)d. Retry up to ' '%(max_retry)d.'), 'cnt': cnt, 'max_retry': max_retry, instance=instance) greenthread.sleep(1)&
14、#160;這個是調(diào)用plug_vifs的函數(shù)中的greenthread.sleep()的函數(shù)調(diào)用,這個函數(shù)多次的發(fā)送請求。except exception.InstanceNotFound: pass greenthread.sleep(0) return disk_over_committed_size 像這樣的栗子還有好多,一般情況下,greenthread.sleep()綠色線程的函數(shù)是為了中止當前的線程,用來給其它的線程一個執(zhí)行的機會。其實說的通俗點就是傳說中的孔融讓梨了,不過此處的梨就是CPU、內(nèi)存等等一些資源了,綠色池中的
15、空間了之類的,突然發(fā)現(xiàn)程序也是那么的有人情味啊loopingcall接下來談?wù)動胠oopingcall實現(xiàn)固定時間間隔運行的函數(shù):def _wait_for_reboot(): state = self.get_info(instance)'state' if state = power_state.RUNNING: LOG.info(_("Instance rebooted successfully."), instance=instance) raise loopingcall.LoopingCallDone() timer = loopingcall.FixedIntervalLoopingCall(_wait_for_reboot) timer.start(interval=0.5).wait() 這個函數(shù)是等待虛機重啟的函數(shù),每隔0.5
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 內(nèi)控制度合同范例
- 會議診斷費用合同范例
- 企業(yè)合同范例英文
- 2手汽車購買合同范例
- 321借款合同范例
- 道路翻新施工方案范本
- 家國情懷素養(yǎng)在高中歷史教學(xué)中的培養(yǎng)研究
- 人工水塔拆除施工方案
- 創(chuàng)業(yè)股權(quán)分配合同范例
- 農(nóng)村蔬菜出租合同范本
- WS 308-2019 醫(yī)療機構(gòu)消防安全管理
- (高鴻業(yè))微觀經(jīng)濟學(xué)習題解析+微觀經(jīng)濟學(xué)題庫解析
- 《尿11-脫氫血栓烷B2與其他危險因素的交互效應(yīng)在急性冠脈綜合征患者中的研究》
- 咨詢公司項目風險控制方案
- 校園食品安全培訓(xùn)課件
- 開關(guān)柜更換改造施工方案
- 《眼科常用眼藥及護》課件
- 污水處理廠防水防腐工程施工方案
- 幕墻作業(yè)安全技術(shù)交底
- TCOSOCC 016-2024 信息技術(shù)應(yīng)用創(chuàng)新 軟件測試要求
- 食堂晨午檢制度
評論
0/150
提交評論