我们可以用下面的代码获取线程的 id 和 name
import threading
# 1 获取线程ID,NAME
t = threading.currentThread()
#线程ID
print('Thread id : %d' % t.ident)
#线程NAME
print('Thread name : %s' % t.getName())
我想知道,怎么获取一个协程的 id 呢?
为什么我会有这个疑问和需求?
因为我在研究 contextvars
threading.local 的隔离效果很好,但是他是针对线程的,隔离线程之间的数据状态。但是现在有了 asyncio,怎么办?
biu~ 我们回到 contextvars,这个模块提供了一组接口,可用于管理、储存、访问局部 Context 的状态。我们看个例子:
❯ cat contextvar_example.py import asyncio import contextvars # 申明Context变量 request_id = contextvars.ContextVar('Id of request') async def get(): # Get Value print(f'Request ID (Inner): {request_id.get()}') async def new_coro(req_id): # Set Value request_id.set(req_id) await get() print(f'Request ID (Outer): {request_id.get()}') async def main(): tasks = [] for req_id in range(1, 5): tasks.append(asyncio.create_task(new_coro(req_id))) await asyncio.gather(*tasks) asyncio.run(main()) ❯ python contextvar_example.py Request ID (Inner): 1 Request ID (Outer): 1 Request ID (Inner): 2 Request ID (Outer): 2 Request ID (Inner): 3 Request ID (Outer): 3 Request ID (Inner): 4 Request ID (Outer): 4
可以看到在数据状态协程之间互不影响。注意上面 contextvars.ContextVar 的传入的第一个参数 (name) 值是一个字符串,它主要是用来标识和调试的,并不一定要用一个单词或者用下划线连起来。
注意,这个模块不仅仅给 aio 加入 Context 的支持,也用来替代
threading.local ()
。
参考文章:
我个人认为,contextvars
可以保存线程和协程级别的变量,应该是通过设置了进程级别的全局变量 xx , xx 是一个字典,key 是 线程或者 协程的 id ,value 就是 value,所以协程 id 怎么获取呢?
作者说过了,与 Greenlet 不同的是,asyncio 没有协程 ID 的概念。
相关 Issue:https://github.com/python/asy...