Webフレームワークでのリクエストの処理の時に、リクエスト等の値をスレッドローカルな値として保持する事がある。おそらく一般的に使用されるフレームワークでは、asyncioを使う場合でも上手くやっているのだろうけれど、そもそもの挙動はどうなっているのだろうかと気になった。そこで、スレッドローカルのようでいてグローバルな変数だった場合に、それぞれのコルーチンの中からはどのように見えるのかを、簡単なasyncioのプログラムを書いて確認する事にした。
import asyncio
import threading
GLOBAL_OBJECT = None
async def work(sleep_second):
global GLOBAL_OBJECT
await asyncio.sleep(sleep_second)
if GLOBAL_OBJECT is None:
print("Update global object")
GLOBAL_OBJECT = threading.local()
print(GLOBAL_OBJECT)
async def main():
await asyncio.gather(
work(1), # work1
work(2), # work2
work(3), # work3
)
asyncio.run(main())
なるほど。普通にグローバル変数として不通に扱われる。まあ、それはそうだよなといった、当たり前の挙動をする事が確認できた。