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してしまうとバグるので
この処理方法はネスト的にあんまりよくない(小泉構文)
随時タスクを追加していく方法であって、別スレッドで処理する方法ではないので注意