- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
就目前而言,我已经找到了很多有关 contextvars 模块如何与 asyncio 配合使用的示例,但没有找到有关如何与线程配合使用的示例(asyncio.get_event_loop().run_in_executor、threading.Thread 等)。
我的问题是,如何将上下文传递给单独的线程?下面您可以看到一个不起作用的代码片段(python 3.9.8)。
import typing
import asyncio
import contextvars
import concurrent.futures
class CustomThreadPoolExecutor(concurrent.futures.ThreadPoolExecutor):
def submit(
self,
function: typing.Callable,
*args,
**kwargs
) -> concurrent.futures.Future:
context = contextvars.copy_context()
return super().submit(
context.run,
functools.partial(function, *args, **kwargs)
)
def function():
print(var.get())
async def main():
await asyncio.get_event_loop().run_in_executor(None, function)
if __name__ == '__main__':
var = contextvars.ContextVar('variable')
var.set('Message.')
asyncio.get_event_loop().set_default_executor(CustomThreadPoolExecutor)
asyncio.run(main())
最佳答案
您可以使用采用 copy_context.items()
的包装函数,设置它们并调用您的函数。 functools.partial
将帮助您创建包装函数以传递给 run_in_executor
。这是我的装饰器的工作测试:
def test_run_in_thread_pool_executor():
def init(func, ctx_vars, *args, **kwargs):
for var, value in ctx_vars:
var.set(value)
return func(*args, **kwargs)
@async_add_headers('streaming')
async def wrapper(f):
loop = asyncio.get_event_loop()
ctx = contextvars.copy_context()
executor = futures.ThreadPoolExecutor(max_workers=5)
return await loop.run_in_executor(executor, functools.partial(init, f, ctx.items()))
@add_headers('client')
def foo():
assert caller_context_var.get() == 'streaming'
async def main_test():
await wrapper(foo)
asyncio.run(main_test())
这里 add_headers
和 async_add_headers
按照调用函数的顺序更改了一些上下文变量。 caller_context_var.get()
将等于没有 init
函数的 'client'
。
不幸的是,它仅适用于 ThreadPoolExecutor,不适用于 ProcessPoolExecutor,因为 Context 对象不可picklable。查看亲戚PEP 567 section 。还有执行器的示例:
executor = ThreadPoolExecutor()
current_context = contextvars.copy_context()
executor.submit(current_context.run, some_function)
关于Python:将上下文(contextvars.Context)复制到单独的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71511061/
将字典设置为 ContextVar 默认值: var: ContextVar[dict] = ContextVar('var', default={}) ...有点管用,因为字典将默认可用,但它总是引
我对 asyncio 和 ContextVars 完全陌生,我刚刚阅读了 3.7 中的新功能并发现了 ContextVars,我很难理解它的用法,我知道它很有用在协程中,而不是使用 thread.lo
如果我在异步网络服务器中有一个结构,例如 import contextvars ... my_context_var = contextvars.ContextVar("var") @app.rout
就目前而言,我已经找到了很多有关 contextvars 模块如何与 asyncio 配合使用的示例,但没有找到有关如何与线程配合使用的示例(asyncio.get_event_loop().run_
我正在尝试在我的数据库框架中管理事务(我使用 MongoDB 和 umongo 而不是 pymongo)。 要使用事务,必须沿整个调用链传递一个session kwarg。我想提供一个上下文管理器来隔
这个问题已经有答案了: How to update global variable in asyncio create_task (2 个回答) 已关闭 3 年前。 我当前有两个无限异步任务正在运行,
我正在使用 Django 2.2 和 Python 3.7 构建单个数据库/共享架构 Multi-Tenancy 应用程序。 我正在尝试使用新的 contextvars API 在 View 之间共享
Python的thread-local data和 ContextVar s 似乎实现了相同的目标(虽然 API 略有不同),唯一面向用户的区别是 ContextVar s 使用异步代码(协程和 as
我是一名优秀的程序员,十分优秀!