本文介绍了跨模块的ContextVar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对asyncio和ContextVars完全陌生,我只是阅读了3.7中的新增功能并发现了ContextVars,我很难理解它的用法,我知道它在协程中很有用,而不是使用thread.local使用ContextVars.但是官方文档和Google排名靠前的搜索结果都无法帮助我真正地了解其目的.

I am completely newb on asyncio and ContextVars, I just read up what's new in 3.7 and discovered ContextVars, I struggle to understand it's usage, all I know it's helpful in coroutines, instead of using thread.local should use ContextVars. But none of the official doc and top google search result could help me truely understand its purpose.

那么,converttvars是否在模块之间共享?我试过了:

So is convextvars shared across modules? I tried:

example.py

example.py

from contextvars import ContextVar

number = ContextVar('number', default=100)
number.set(1)

然后我尝试导入number.py

then I try to import number.py

(playground) Jamess-MacBook-Pro-2:playground jlin$ python3.7
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> from contextvars import ContextVar
>>> number = ContextVar('number', default=200)
>>> number.get()
200

我原本以为number.get()会返回1,但是显然我理解它的目的是错误的.

I was expecting number.get() would return 1, but obviously I have understood its purpose wrong.

有人可以帮助我理解这一点吗?

Could someone please help me understand this?

推荐答案

假设您的用例是使用python thread.local将线程全局变量存储在多线程应用程序中.

Assume your use case is to use python thread.local to store your thread global variable inside multi thread application.

例如,您将django request全局存储在thread.local

For example you store django request globally in thread.local

  • 您所有的代码都可以访问当前(和正确的)request实例
  • 它有效,因为每个django HTTP请求都在其自己的python线程中处理
  • all your code has access to current (and correct) request instance
  • it works, because each django HTTP request handled in it's own python thread

不要想象您将asyncio中的HTTP请求作为在同一python线程中执行的非阻塞代码来处理.

No imagine you handle HTTP requests in asyncio as non blocking code executed in the same python thread.

  • 存储在thread.local中的HTTP请求无法正常工作,因为多个并发请求在同一个python线程中得到处理
  • 会发生什么情况?您覆盖相同的thread.local变量,并且您的所有代码都可以访问最新的(错误的)request实例
  • HTTP request stored in thread.local isn't going to work, because multiple concurrent requests get processed in the same python thread
  • What happens is you overwrite same thread.local variable and all your code has access to latest (incorrect) request instance

在这种情况下,您将使用ContextVars设计用于该用例,以在同一python线程中运行的非阻塞并发作业中使用.

In this case you use ContextVars designed to be used for this use case inside non blocking concurrent jobs running in same python thread.

这篇关于跨模块的ContextVar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 07:21