0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

python asyncio func Aが終わらない場合はfunc Bを追加し続ける

Last updated at Posted at 2021-03-11

python 3.9.2

asyncio.キューはよくわからんし使いたくないので、それ以外の方法でタスクを追加し続けるやつ

import asyncio

async def run_in_executor_A():
    #メインで長時間かかる処理
    def A():
        #一般的な処理
        print("Aを実行")
        sum([i*i for i in range(10**8)])
    loop = asyncio.get_running_loop()
    await loop.run_in_executor(None, A)

async def run_in_executor_B():
    #Aが終わらない時に追加で処理したい
    def B():
        #一般的な処理
        print("Bを実行")
        sum([i*i for i in range(10**7)])
    loop = asyncio.get_running_loop()
    await loop.run_in_executor(None, B)




async def stack_Deal():
    #run_in_executor_Aというコルーチンを生成、タスクとして走らせる
    MainTask=asyncio.create_task(run_in_executor_A())
    #タスクに名前を付与
    MainTask.set_name("タスクA")
    while 1:
        await asyncio.sleep(1)
        active_tasks = [task.get_name() for task in asyncio.all_tasks()]
        print(active_tasks)
        #タスクAが終了している場合は他のタスクを全て終了してループをbreak
        if not "タスクA" in active_tasks:
            for task in asyncio.all_tasks():
                if "タスク" in task.get_name():
                    task.cancel()
            break

        #タスクBが存在しない場合はrun_in_executor_Bのコルーチンを生成してタスクとして走らせる
        if not "タスクB" in active_tasks:
            TaskB=asyncio.create_task(run_in_executor_B())
            TaskB.set_name("タスクB")

if __name__ == '__main__':
    asyncio.run(stack_Deal())

実行結果

Aを実行
['Task-1', 'タスクA']
Bを実行
['Task-1', 'タスクB', 'タスクA']
['Task-1', 'タスクA']
Bを実行
['Task-1', 'タスクB', 'タスクA']
['Task-1', 'タスクA']
Bを実行
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1']
Bを実行
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1']
Bを実行
['タスクA', 'Task-1', 'タスクB']
['タスクA', 'Task-1', 'タスクB']
['Task-1']

asyncio.all_tasks()はすべての実行中のタスクを表示するので、ネスト的にあんまりよくない

stack_Dealが非同期関数である以上
stack_Deal()もコルーチンとなるため
asyncio.run(stack_Deal())もタスクとして表示される
タスクの名前は'Task-1'から自動的に振られていく

なので'Task-1'内部で'Task-1'をcancelしてしまうとバグるので
この処理方法はネスト的にあんまりよくない(小泉構文)

随時タスクを追加していく方法であって、別スレッドで処理する方法ではないので注意

0
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?