Python3:讓不支持async的函數(shù)實現(xiàn)異步操作

asyncio是Python3引入的異步IO功能乙墙,主要是在語言層面上解決IO阻塞的問題生均。

常規(guī)的用法是在主函數(shù)中運行run_until_complete這個函數(shù)。但是有的時候汉买,代碼中使用的第三方庫也需要在主函數(shù)中運行自己的循環(huán)函數(shù)佩脊,比如PyQt。那么run_until_complete這個函數(shù)就無法調(diào)用了威彰。

我嘗試了下創(chuàng)建一個新的loop對象钧敞,在線程中調(diào)用loop對象的循環(huán)函數(shù)满粗,解決了這個問題调煎。

# 創(chuàng)建一個loop循環(huán)

new_loop = asyncio.new_event_loop()

# 定義線程函數(shù)

def Loop(loop):

? ??while True:

? ??????try:

? ??????????loop.run_forever()? ? # 這里調(diào)用了asynicio的循環(huán)函數(shù)

? ??????except KeyboardInterrupt:? ? # 按ctrl-c能退出

? ??????????loop.close()

# 創(chuàng)建一個線程巡揍,在線程里面執(zhí)行 run_forever

t = threading.Thread(target = Loop, args=(new_loop,))

t.daemon = True

t.start()

while True: # 這里是模擬其他庫的阻塞函數(shù)

? ? pass

在上面的代碼里面耿眉,創(chuàng)建好了異步調(diào)用的流程,接下來是如何調(diào)用不支持asyncio的函數(shù)鸣剪。拿requests來舉例吧丈积。

requests是python下常用的web請求庫债鸡。我們知道http請求是很費時的,調(diào)用一次幾十到幾百毫秒的阻塞唬滑。

現(xiàn)在實現(xiàn)一個異步的請求:

def PostFinishTask(action_id):

? ??asyncio.run_coroutine_threadsafe(PostFinishTaskAsync(action_id), new_loop)

用到的變量是剛才創(chuàng)建的new_loop對象棺弊,表示本次異步調(diào)用會在剛創(chuàng)建的線程里面執(zhí)行,不會阻塞主線程稻艰。

async def PostFinishTaskAsync(action_id):

? ??payload = {?'action_id': action_id }? ? # 模擬的一些網(wǎng)絡(luò)參數(shù)

? ??def Do_post(): # 為了解決傳參的問題侈净,定義一個內(nèi)部函數(shù)

? ??????return requests.post("https://some_call_url", data = payload)

? ??future = new_loop.run_in_executor(None, Do_post)?

????response = await future # 等待調(diào)用完成

這個PostFinishTaskAsync函數(shù)才是真正干活的函數(shù)。首先加上async运怖,然后為了解決run_in_executor無法給它回調(diào)的函數(shù)傳多個參數(shù)拼弃,額外的定義了一個Do_post函數(shù)用來繞過。

經(jīng)過以上改造溺忧,requests變成了非阻塞的調(diào)用了盯孙。

本文解決了兩個問題,一個是如何自定義一個asyncio的loop循環(huán)歌溉。另一個是如何把阻塞函數(shù)改成非阻塞。雖然Python是一個很慢的語言痛垛,但是將IO改造成非阻塞桶蛔,在一定的場合下還是能工作的不錯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蹂析,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子电抚,更是在濱河造成了極大的恐慌,老刑警劉巖缩宜,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甥温,死亡現(xiàn)場離奇詭異,居然都是意外死亡宋梧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門捂龄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倦沧,“玉大人它匕,你說我怎么就攤上這事≡ゼ恚” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵燕偶,是天一觀的道長础嫡。 經(jīng)常有香客問我,道長伯诬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任姑廉,我火速辦了婚禮桥言,結(jié)果婚禮上萌踱,老公的妹妹穿的比我還像新娘并鸵。我一直安慰自己,他們只是感情好园担,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咏闪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸽嫂。 梳的紋絲不亂的頭發(fā)上征讲,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音癣籽,去河邊找鬼扳还。 笑死橱夭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棘劣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼首昔,長吁一口氣:“原來是場噩夢啊……” “哼糙俗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起巧骚,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤格二,失蹤者是張志新(化名)和其女友劉穎顶猜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體长窄,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡挠日,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年翰舌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灶芝。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡夜涕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出女器,到底是詐尸還是另有隱情,我是刑警寧澤驾胆,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布丧诺,位于F島的核電站,受9級特大地震影響驳阎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呵晚,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一饵隙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧金矛,春花似錦倘潜、人聲如沸志于。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至澜掩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肩榕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工株汉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留乔妈,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓路召,卻偏偏與公主長得像波材,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子廷区,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容