标签: asyncio

如何编写一致的有状态上下文管理器?

编辑:正如指出的蒂埃里LathuillePEP567,在那里ContextVar被引入,却没有设计地址发生器(不像撤回PEP550)。尽管如此,主要问题仍然存在。如何编写可在多个线程,生成器和asyncio任务中正常运行的有状态上下文管理器?


我有一个带有一些可以在不同“模式”下运行的功能的库,因此可以通过本地上下文来更改其行为。我正在查看contextvars可靠地实现此功能的模块,因此可以在不同的线程,异步上下文等环境中使用它。但是,我很难获得一个正确的简单示例。考虑以下最小设置:

from contextlib import contextmanager
from contextvars import ContextVar

MODE = ContextVar('mode', default=0)

@contextmanager
def use_mode(mode):
    t = MODE.set(mode)
    try:
        yield
    finally:
        MODE.reset(t)

def print_mode():
   print(f'Mode {MODE.get()}')
Run Code Online (Sandbox Code Playgroud)

这是一个带有生成器功能的小测试:

def first():
    print('Start first')
    print_mode()
    with use_mode(1):
        print('In first: with use_mode(1)')
        print('In first: start second')
        it = second()
        next(it)
        print('In first: back from second')
        print_mode()
        print('In first: continue second')
        next(it, None)
        print('In first: finish')

def second():
    print('Start second')
    print_mode() …
Run Code Online (Sandbox Code Playgroud)

python python-contextvars asyncio

5
推荐指数
1
解决办法
258
查看次数

路由挂起中的Python3 Flask asyncio子进程

我在Ubuntu 18.04上将Flask 1.0.2与Python 3.6一起使用。我的应用程序应使用asyncio并asyncio.create_subprocess_exec()启动后台脚本,从中读取stdout,然后在脚本完成后返回状态。

我基本上是想从这篇文章中实现一个答案: 在Python的subprocess.PIPE上非阻塞读取

该脚本已成功启动,并且从中获得了所有预期的输出,但是问题是它从不返回(意味着Killing subprocess now从不到达该行)。当我ps从Linux终端检查进程列表()时,后台脚本已退出。

我在做什么错,如何才能成功摆脱困境async for line in process.stdout

导入后,在文件顶部,创建事件循环:

# Create a loop to run all the tasks in.
global eventLoop ; asyncio.set_event_loop(None)
eventLoop = asyncio.new_event_loop()
asyncio.get_child_watcher().attach_loop(eventLoop)
Run Code Online (Sandbox Code Playgroud)

我在路线上方定义了异步协程:

async def readAsyncFunctionAndKill(cmd):
    # Use global event loop
    global eventLoop

    print("[%s] Starting async Training Script ..." % (os.path.basename(__file__)))
    process = await asyncio.create_subprocess_exec(cmd,stdout=PIPE,loop=eventLoop)
    print("[%s] Starting to read stdout ..." % (os.path.basename(__file__)))
    async for line in process.stdout:
        line = line.decode(locale.getpreferredencoding(False)) …
Run Code Online (Sandbox Code Playgroud)

python linux flask python-3.x asyncio

1
推荐指数
1
解决办法
168
查看次数

标签 统计

asyncio ×2

python ×2

flask ×1

linux ×1

python-3.x ×1

python-contextvars ×1