第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

用于遷移現(xiàn)有代碼庫的線程中的 Python asyncio

用于遷移現(xiàn)有代碼庫的線程中的 Python asyncio

偶然的你 2023-05-09 15:36:55
我們有一個(gè)相當(dāng)大的項(xiàng)目,它正在做大量的網(wǎng)絡(luò)(API 調(diào)用、Websocket 消息),并且還有很多內(nèi)部作業(yè)在線程中間隔運(yùn)行。我們當(dāng)前的架構(gòu)涉及生成大量線程,當(dāng)系統(tǒng)負(fù)載很大時(shí),應(yīng)用程序無法正常運(yùn)行,因此我們決定嘗試使用 asyncio。我知道最好的方法是將整個(gè)代碼庫遷移到異步代碼,但由于代碼庫的大小和有限的開發(fā)資源,這在不久的將來是不現(xiàn)實(shí)的。但是,我們希望開始遷移部分代碼庫以使用 asyncio 事件循環(huán),并希望我們能夠在某個(gè)時(shí)候轉(zhuǎn)換整個(gè)項(xiàng)目。到目前為止我們遇到的問題是整個(gè)代碼庫都有同步代碼,為了在里面添加非阻塞異步代碼,代碼需要在不同的線程中運(yùn)行,因?yàn)槟悴荒苷嬲谕粋€(gè)線程中運(yùn)行異步和同步代碼線。為了結(jié)合異步和同步代碼,我想出了這種在應(yīng)用程序啟動(dòng)時(shí)創(chuàng)建的單獨(dú)線程中運(yùn)行異步代碼的方法。代碼的其他部分只需調(diào)用 add_asyncio_task 即可將作業(yè)添加到此循環(huán)中。import threadingimport asyncio_tasks = []def threaded_loop(loop):    asyncio.set_event_loop(loop)    global _tasks    while True:        if len(_tasks) > 0:            # create a copy of needed tasks            needed_tasks = _tasks.copy()            # flush current tasks so that next tasks can be easily added            _tasks = []            # run tasks            task_group = asyncio.gather(*needed_tasks)            loop.run_until_complete(task_group)def add_asyncio_task(task):    _tasks.append(task)def start_asyncio_loop():    loop = asyncio.get_event_loop()    t = threading.Thread(target=threaded_loop, args=(loop,))    t.start()在 app.py 的某處:start_asyncio_loop()以及代碼中的其他任何地方:add_asyncio_task(some_coroutine)由于我是 asyncio 的新手,我想知道在我們的情況下這是否是一種好方法,或者這種方法是否被認(rèn)為是一種反模式并且有一些問題會(huì)在以后的道路上打擊我們?或者也許 asyncio 已經(jīng)有了一些解決方案,而我只是想在這里發(fā)明輪子?感謝您的投入!
查看完整描述

1 回答

?
慕后森

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊

這種方法總體上很好。你有一些問題:

(1)幾乎所有的asyncio對(duì)象都不是線程安全的

(2) 您的代碼本身不是線程安全的。如果任務(wù)出現(xiàn)在之后needed_tasks = _tasks.copy()但之前怎么辦_tasks = []?這里需要一把鎖。順便說一句,復(fù)制是沒有意義的。簡(jiǎn)單needed_tasks = _tasks就行了。

(3) 一些 asyncio 結(jié)構(gòu)是線程安全的。使用它們:

import threading

import asyncio


# asyncio.get_event_loop() creates a new loop per thread. Keep

# a single reference to the main loop. You can even try

#? ?_loop = asyncio.new_event_loop()

_loop = asyncio.get_event_loop()


def get_app_loop():

? ? return _loop


def asyncio_thread():

? ? loop = get_app_loop()

? ? asyncio.set_event_loop(loop)

? ? loop.run_forever()


def add_asyncio_task(task):

? ? asyncio.run_coroutine_threadsafe(task, get_app_loop())


def start_asyncio_loop():

? ? t = threading.Thread(target=asyncio_thread)

? ? t.start()


查看完整回答
反對(duì) 回復(fù) 2023-05-09
  • 1 回答
  • 0 關(guān)注
  • 126 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)