Pythonで複数の外部リソースへのアクセスとその処理を1つのまとまりとして、並行処理させたいです
そこで、以下のようなコードを書いています(実際の処理などは抽象化しますが、tweepy
やrequests
などのライブラリを使っています)
しかし、実際はasyncio.create_task
によって作られたタスクが順々に実行されてしまいます
python
1def download(url): 2 ... 3 return sentence 4 5def text_preprocess(sentence): 6 ... 7 return 8 9async def download_and_preprocess(url): 10 sentence = download(url) 11 return preprocess(sentence) 12 13 14def main(): 15 urls = [...] 16 loop = asyncio.get_event_loop() 17 tasks = [asyncio.create_task(download_and_preprocess(url) for url in urls] 18 loop.run_until_complete(asyncio.gather(*tasks)) 19 20main()
私の理解では
download_and_preprocess
を呼び出すとcoroutineオブジェクトが返ってくるasyncio.create_task
に coroutineオブジェクトを渡すと、Task
になるTask
オブジェクトは並行して実行される
と理解しています
期待しているのは
- 各
download_and_preprocess
が並行に実行され、 loop.run_until_complete
などでその配列を受取ることです
そこで別の実験として以下の様に書いて実験しました
python
1async def r(i): 2 print(f"start {i}") 3 time.sleep(10-i) 4 return i 5async def main(): 6 tasks = [asyncio.create_task(r(x)) for x in range(5)] 7 for task in tasks: 8 print(await task) 9 return 10asyncio.run(main())
実行してみると
console
1start 0 2start 1 3start 2 4start 3 5start 4 60 71 82 93 104
と、出力されます
特にstart {i}
を出力するのに10-i
かかってしまいます(ここは並行して出て欲しい)
time.sleep
をawait asyncio.sleep
に変更すると期待したような動きをするのは確認できました
結局、最初のdownload_and_preprocess
を期待通り実行させるにはどうしたら良いのでしょうか
どなたかご存じの方いらっしゃればご教示願いたいです
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/08/07 00:11
2020/08/07 02:27
2020/08/07 04:02
2020/08/07 05:06