簡體   English   中英

如何異步運行周期性任務和while循環

[英]How to run a periodic task and a while loop asynchronously

我有兩個功能:

i = 0

def update():
    global i
    i += 1

def output():
    print(i)

我想每 3 秒運行一次output()並在沒有任何間隔的情況下循環update() ,當然都是異步的。

我嘗試使用asynciothreadingmultithreadingtimeloop但我無法讓它在這兩個庫中工作。 如果您知道如何在這些庫中的任何一個或其他庫中執行此操作,請提供幫助。 我可以與任何圖書館合作。

使用 AsyncIO 這將類似於:

import asyncio


def update(value):
    value["int"] += 1

def output(value):
    print(value["int"])

async def update_worker(value):
    while True:
        update(value)
        await asyncio.sleep(0)

async def output_worker(value):
    while True:
        output(value)
        await asyncio.sleep(3)

async def main():
    value = {"int": 0}

    await asyncio.gather(
        update_worker(value), 
        output_worker(value))


if __name__ == "__main__":
    asyncio.run(main())

請注意,我將全局值更改為共享值,因為這樣做是最佳實踐。 在其他編程語言中,在讀取和寫入多個並發上下文時共享一個值是不安全的,但由於大多數 Python 對象都是線程安全的,在這種情況下是可以的。 否則,您應該使用任何其他並發原語的互斥鎖來同步讀取和寫入。

AsyncIO並發基於協作式多任務模型,因此異步任務在等待某事時必須明確將控制權讓給其他並發任務(所有await關鍵字都注明)。 因此,為了確保output_worker有機會運行,必須在 update_worker 的無限循環中添加 await update_worker await asyncio.sleep(0) ,以便 AsyncIO 事件循環可以運行output_worker

這是使用多線程而不是 AsyncIO 的相同代碼:

from time import sleep
from threading import Thread, Lock

def update(value, lock):
    with lock:
        value["int"] += 1

def output(value, lock):
    with lock:
        print(value["int"])

def update_worker(value, lock):
    while True:
        update(value, lock)

def output_worker(value, lock):
    while True:
        output(value, lock)
        sleep(3)

def main():
    value = {"int": 0}
    lock = Lock()

    t1 = Thread(target=update_worker, args=(value, lock), daemon=True)
    t2 = Thread(target=output_worker, args=(value, lock), daemon=True)

    t1.start()
    t2.start()

    t1.join()
    t2.join()

if __name__ == "__main__":
    main()

盡管在這個特定的 Python 程序中沒有必要,但我使用Lock來同步讀取和寫入,因為它是處理並發的正確方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM