国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Python > 正文

使用Python中的greenlet包實(shí)現(xiàn)并發(fā)編程的入門教程

2020-02-23 00:46:09
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

1   動(dòng)機(jī)

greenlet 包是 Stackless 的副產(chǎn)品,其將微線程稱為 “tasklet” 。tasklet運(yùn)行在偽并發(fā)中,使用channel進(jìn)行同步數(shù)據(jù)交換。

一個(gè)”greenlet”,是一個(gè)更加原始的微線程的概念,但是沒(méi)有調(diào)度,或者叫做協(xié)程。這在你需要控制你的代碼時(shí)很有用。你可以自己構(gòu)造微線程的 調(diào)度器;也可以使用”greenlet”實(shí)現(xiàn)高級(jí)的控制流。例如可以重新創(chuàng)建構(gòu)造器;不同于Python的構(gòu)造器,我們的構(gòu)造器可以嵌套的調(diào)用函數(shù),而被 嵌套的函數(shù)也可以 yield 一個(gè)值。(另外,你并不需要一個(gè)”yield”關(guān)鍵字,參考例子)。

Greenlet是作為一個(gè)C擴(kuò)展模塊給未修改的解釋器的。

1.1   例子

假設(shè)系統(tǒng)是被控制臺(tái)程序控制的,由用戶輸入命令。假設(shè)輸入是一個(gè)個(gè)字符的。這樣的系統(tǒng)有如如下的樣子:

def process_commands(*args):  while True:    line=''    while not line.endswith('/n'):      line+=read_next_char()    if line=='quit/n':      print "are you sure?"      if read_next_char()!="y":        continue  #忽略指令    process_commands(line)

現(xiàn)在假設(shè)你要把程序移植到GUI,而大多數(shù)GUI是事件驅(qū)動(dòng)的。他們會(huì)在每次的用戶輸入時(shí)調(diào)用回調(diào)函數(shù)。這種情況下,就很難實(shí)現(xiàn) read_next_char() 函數(shù)。我們有兩個(gè)不兼容的函數(shù):

def event_keydown(key):
    ??

def read_next_char():
    ?? 需要等待 event_keydown() 的調(diào)用

你可能在考慮用線程實(shí)現(xiàn)。而 Greenlet 是另一種解決方案,沒(méi)有鎖和關(guān)閉問(wèn)題。你啟動(dòng) process_commands() 函數(shù),分割成 greenlet ,然后與按鍵事件交互,有如:

def event_keydown(key):  g_processor.switch(key)def read_next_char():  g_self=greenlet.getcurrent()  next_char=g_self.parent.switch()  #跳到上一層(main)的greenlet,等待下一次按鍵  return next_charg_processor=greenlet(process_commands)g_processor.switch(*args)gui.mainloop()

這個(gè)例子的執(zhí)行流程是: read_next_char() 被調(diào)用,也就是 g_processor 的一部分,它就會(huì)切換(switch)到他的父greenlet,并假設(shè)繼續(xù)在頂級(jí)主循環(huán)中執(zhí)行(GUI主循環(huán))。當(dāng)GUI調(diào)用 event_keydown() 時(shí),它切換到 g_processor ,這意味著執(zhí)行會(huì)跳回到原來(lái)掛起的地方,也就是 read_next_char() 函數(shù)中的切換指令那里。然后 event_keydown() 的 key 參數(shù)就會(huì)被傳遞到 read_next_char() 的切換處,并返回。

注意 read_next_char() 會(huì)被掛起并假設(shè)其調(diào)用棧會(huì)在恢復(fù)時(shí)保護(hù)的很好,所以他會(huì)在被調(diào)用的地方返回。這允許程序邏輯保持優(yōu)美的順序流。我們無(wú)需重寫 process_commands() 來(lái)用到一個(gè)狀態(tài)機(jī)中。

2   使用

2.1   簡(jiǎn)介

一個(gè) “greenlet” 是一個(gè)很小的獨(dú)立微線程。可以把它想像成一個(gè)堆棧幀,棧底是初始調(diào)用,而棧頂是當(dāng)前greenlet的暫停位置。你使用greenlet創(chuàng)建一堆這樣的堆 棧,然后在他們之間跳轉(zhuǎn)執(zhí)行。跳轉(zhuǎn)不是絕對(duì)的:一個(gè)greenlet必須選擇跳轉(zhuǎn)到選擇好的另一個(gè)greenlet,這會(huì)讓前一個(gè)掛起,而后一個(gè)恢復(fù)。兩 個(gè)greenlet之間的跳轉(zhuǎn)稱為 切換(switch) 。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 通江县| 于田县| 开原市| 兰溪市| 镇巴县| 石嘴山市| 拜泉县| 景宁| 政和县| 米林县| 永清县| 丰县| 金湖县| 军事| 呼图壁县| 卢湾区| 明水县| 乡宁县| 白沙| 城口县| 龙口市| 柏乡县| 紫金县| 玉环县| 长沙市| 桓台县| 海丰县| 三明市| 大埔县| 华蓥市| 安顺市| 乃东县| 镇雄县| 百色市| 菏泽市| 景谷| 五常市| 崇仁县| 囊谦县| 柳河县| 枣庄市|