问题描述
我对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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!