Skip to content

Instantly share code, notes, and snippets.

@ryu22e
Last active November 14, 2024 13:08
Show Gist options
  • Save ryu22e/31595bbaf94aa9ec3204651c28e86841 to your computer and use it in GitHub Desktop.
Save ryu22e/31595bbaf94aa9ec3204651c28e86841 to your computer and use it in GitHub Desktop.
PyCon mini 東海 2024発表資料サンプルコード
thread_id=8323698496 (step1_unique_id='9484892561164a18af996c2cf7ab6c2f') == (step3_unique_id='9484892561164a18af996c2cf7ab6c2f')
thread_id=8323698496 (step1_unique_id='2f7b73f1301648f3a6cf4a8b2d29f559') == (step3_unique_id='2f7b73f1301648f3a6cf4a8b2d29f559')
thread_id=8323698496 (step1_unique_id='9fc06c8056184fc88c1f3af56e77330d') == (step3_unique_id='9fc06c8056184fc88c1f3af56e77330d')
"""asgiref.local.Localのサンプルコード(コルーチン)"""
import threading
import asyncio
import uuid
from asgiref.local import Local
local_storage = Local() # ここを変えただけ
async def test_task(wait):
# スレッドID取得
thread_id = threading.get_ident()
# 1. ユニークIDをローカルストレージに設定
step1_unique_id = uuid.uuid4().hex
local_storage.unique_id = step1_unique_id
# 2. wait秒待つ
await asyncio.sleep(wait)
# 3. wait秒待機後のユニークIDを取得
step3_unique_id = getattr(local_storage, "unique_id", None)
equal_or_not = "==" if step1_unique_id == step3_unique_id else "!="
print(f"{thread_id=} ({step1_unique_id=}) {equal_or_not} ({step3_unique_id=})")
async def main():
tasks = (
test_task(3),
test_task(2),
test_task(1),
)
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
thread_id=6140276736 (step1_unique_id='43faa0bb3add4921b1e2649af269646e') == (step3_unique_id='43faa0bb3add4921b1e2649af269646e')
thread_id=6123450368 (step1_unique_id='d244e874e5f74940a944895c641302c3') == (step3_unique_id='d244e874e5f74940a944895c641302c3')
thread_id=6106624000 (step1_unique_id='4ed999ac3ad04dbaafa26eda3ad71a0b') == (step3_unique_id='4ed999ac3ad04dbaafa26eda3ad71a0b')
"""asgiref.local.Localのサンプルコード(マルチスレッド)"""
import uuid
import time
import threading
from asgiref.local import Local
local_storage = Local() # ここを変えただけ
def test_task(wait):
# スレッドID取得
thread_id = threading.get_ident()
# 1. ユニークIDをローカルストレージに設定
step1_unique_id = uuid.uuid4().hex
local_storage.unique_id = step1_unique_id
# 2. wait秒待つ
time.sleep(wait)
# 3. wait秒待機後のユニークIDを取得
# (他のスレッドが値を上書きしていないはず)
step3_unique_id = getattr(local_storage, "unique_id", None)
equal_or_not = "==" if step1_unique_id == step3_unique_id else "!="
print(f"{thread_id=} ({step1_unique_id=}) {equal_or_not} ({step3_unique_id=})")
def main():
# 待機時間が異なるスレッドを3つ立ち上げる
threads = [
threading.Thread(target=test_task, args=(3,)),
threading.Thread(target=test_task, args=(2,)),
threading.Thread(target=test_task, args=(1,)),
]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
if __name__ == "__main__":
main()
thread_id=8308739904 (step1_unique_id='011b6db1ddca48b2a353667e9c79f34a') == (step3_unique_id='011b6db1ddca48b2a353667e9c79f34a')
thread_id=8308739904 (step1_unique_id='dcfc53f6ec9149f99838a6815608c12b') == (step3_unique_id='dcfc53f6ec9149f99838a6815608c12b')
thread_id=8308739904 (step1_unique_id='42ee7264770745a6b90b9e5e98082a57') == (step3_unique_id='42ee7264770745a6b90b9e5e98082a57')
"""contextvars.ContextVarのサンプルコード"""
import threading
from contextvars import ContextVar
import asyncio
import uuid
# threading.localの説明の際に見せた、コルーチンの例とほぼ同じコード。
# コンテキスト変数を宣言
local_storage = ContextVar("local_storage", default=None)
async def test_task(wait):
step1_unique_id = uuid.uuid4().hex
thread_id = threading.get_ident()
# 値の設定はset()メソッドで行う(設定できる値は1個のみ)
local_storage.set(step1_unique_id)
await asyncio.sleep(wait)
# 値の取得はget()メソッドで行う
step3_unique_id = local_storage.get()
equal_or_not = "==" if step1_unique_id == step3_unique_id else "!="
print(f"{thread_id=} ({step1_unique_id=}) {equal_or_not} ({step3_unique_id=})")
async def main():
tasks = (
test_task(3),
test_task(2),
test_task(1),
)
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
thread_id=8370802496 (step1_unique_id='b8e9a1f3e8714831b2aa8275fa47b8f1') == (step3_unique_id='b8e9a1f3e8714831b2aa8275fa47b8f1')
thread_id=8370802496 (step1_unique_id='cdd46248fbe44f57a2a488919add7d1e') != (step3_unique_id='b8e9a1f3e8714831b2aa8275fa47b8f1')
thread_id=8370802496 (step1_unique_id='39eb437c91e8437dae500b91e36bb3ff') != (step3_unique_id='b8e9a1f3e8714831b2aa8275fa47b8f1')
"""threading.localのサンプルコード(コルーチン"""
import threading
import asyncio
import uuid
local_storage = threading.local()
async def test_task(wait):
step1_unique_id = uuid.uuid4().hex
thread_id = threading.get_ident()
local_storage.unique_id = step1_unique_id
# ここで待機中に別のコルーチンでlocal_storage.unique_idを上書きしてしまう場合がある。
await asyncio.sleep(wait)
step3_unique_id = getattr(local_storage, "unique_id", None)
equal_or_not = "==" if step1_unique_id == step3_unique_id else "!="
print(f"{thread_id=} ({step1_unique_id=}) {equal_or_not} ({step3_unique_id=})")
async def main():
tasks = (
test_task(3),
test_task(2),
test_task(1),
)
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
thread_id=6173028352 (step1_unique_id='0863e8995b064f3e9c24ed1dbe926577') == (step3_unique_id='0863e8995b064f3e9c24ed1dbe926577')
thread_id=6156201984 (step1_unique_id='0fe21b299ab34f7e83fb979277ccce3a') == (step3_unique_id='0fe21b299ab34f7e83fb979277ccce3a')
thread_id=6139375616 (step1_unique_id='2e7e9d7b8b59439dbd73fc826e45cc32') == (step3_unique_id='2e7e9d7b8b59439dbd73fc826e45cc32')
"""threading.localのサンプルコード(マルチスレッド)"""
import uuid
import time
import threading
from threading import local
local_storage = local()
def test_task(wait):
# スレッドID取得
thread_id = threading.get_ident()
# 1. ユニークIDをローカルストレージに設定
step1_unique_id = uuid.uuid4().hex
local_storage.unique_id = step1_unique_id
# 2. wait秒待つ
time.sleep(wait)
# 3. wait秒待機後のユニークIDを取得
# (他のスレッドが値を上書きしていないはず)
step3_unique_id = getattr(local_storage, "unique_id", None)
equal_or_not = "==" if step1_unique_id == step3_unique_id else "!="
print(f"{thread_id=} ({step1_unique_id=}) {equal_or_not} ({step3_unique_id=})")
def main():
# 待機時間が異なるスレッドを3つ立ち上げる
threads = [
threading.Thread(target=test_task, args=(3,)),
threading.Thread(target=test_task, args=(2,)),
threading.Thread(target=test_task, args=(1,)),
]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
if __name__ == "__main__":
main()
thread_id=6187102208 (step1_unique_id='512dffda46f44e6bbd12c01bba4d4f3c') == (step3_unique_id='512dffda46f44e6bbd12c01bba4d4f3c')
thread_id=6170275840 (step1_unique_id='0f5912e47aee412f9342c2e49bf96d2c') != (step3_unique_id='512dffda46f44e6bbd12c01bba4d4f3c')
thread_id=6153449472 (step1_unique_id='b1587085778e49f789fc02fb73f1ce9b') != (step3_unique_id='512dffda46f44e6bbd12c01bba4d4f3c')
import uuid
import time
import threading
# もし、threading.local以外のオブジェクトを使ったら
class LocalStorage: ...
local_storage = LocalStorage()
def test_task(wait):
# スレッドID取得
thread_id = threading.get_ident()
# 1. ユニークIDをローカルストレージに設定
step1_unique_id = uuid.uuid4().hex
local_storage.unique_id = step1_unique_id
# 2. wait秒待つ
time.sleep(wait)
# 3. wait秒待機後のユニークIDを取得
# (他のスレッドが値を上書きしていないはず)
step3_unique_id = getattr(local_storage, "unique_id", None)
equal_or_not = "==" if step1_unique_id == step3_unique_id else "!="
print(f"{thread_id=} ({step1_unique_id=}) {equal_or_not} ({step3_unique_id=})")
def main():
# 待機時間が異なるスレッドを3つ立ち上げる
threads = [
threading.Thread(target=test_task, args=(3,)),
threading.Thread(target=test_task, args=(2,)),
threading.Thread(target=test_task, args=(1,)),
]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment