python asyncio 如何获取当前的协程 id 编号

我们可以用下面的代码获取线程的 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模块到底是做什么的?

我个人认为,contextvars 可以保存线程和协程级别的变量,应该是通过设置了进程级别的全局变量 xx , xx 是一个字典,key 是 线程或者 协程的 id ,value 就是 value,所以协程 id 怎么获取呢?

阅读 5.1k
1 个回答
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题