标签: python-asyncio

使用 Asyncio 的非阻塞 Websocket 接收

我正在开发一个 Python-3 程序,它试图做两件事:(1)从外部 websocket(非阻塞)读取数据(类型 1)和(2)在常规 UDP 上接收数据(类型 2)套接字(非阻塞)

有很长一段时间,websocket 和 UDP 套接字上都没有数据。因此,我试图对两种数据类型进行非阻塞读取/接收。我正在尝试使用 Asyncio 和 Websockets 为 websocket 执行此操作。

不幸的是,只要 websocket 上没有数据(类型 1),下面的代码就会挂起。它阻止了其余代码的执行。我究竟做错了什么?

在此先感谢您的帮助。

import asyncio
import websockets
import socket

IP_STRATUX =    "ws://192.168.86.201/traffic"

# Method to retrieve data (Type 1) from websocket
async def readWsStratux(inURL):
    async with websockets.connect(inURL, close_timeout=0.1) as websocket:
        try:
            data = await websocket.recv()
            return data
        except websocket.error:
            return None

if __name__ == "__main__":
    # Socket to receive data (Type 2)
    sockPCC = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sockPCC.bind((PCC_IP, PCC_PORT))
    sockPCC.setblocking(0)

    while …
Run Code Online (Sandbox Code Playgroud)

python-3.x python-asyncio

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

如何在 Python 中编写自己的异步/等待协程函数?

我正在尝试编写我自己的 awaiatbale 函数,该函数可以在异步循环中使用,例如asyncio.sleep()方法或类似这些预等待实现的方法。

这是我到目前为止所做的:

import asyncio

def coro1():
    for i in range(1, 10):
        yield i

def coro2():
    for i in range(1, 10):
        yield i*10

class Coro:  # Not used.
    def __await__(self):
        for i in range(1, 10):
            yield i * 100

@asyncio.coroutine
def wrapper1():
    return (yield from coro1())

@asyncio.coroutine
def wrapper2():
    return (yield from coro2())

for i in wrapper1():
    print(i)

print("Above result was obvious which I can iterate around a couroutine.".center(80, "#"))

async def async_wrapper():
    await wrapper1()
    await wrapper2() …
Run Code Online (Sandbox Code Playgroud)

python python-3.x async-await python-asyncio

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

如何在 jupyter lab 上使用异步小部件?

如何在 jupyter lab上使用异步小部件?

我正在尝试在 jupyter lab上重现官方的 Asynchronous Widgets-Example,但从未继续。await

设置/再现

  1. docker run --rm -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes jupyter/datascience-notebook start-notebook.sh --NotebookApp.token=''
  2. firefox 0.0.0.0:8888
  3. 创建一个新的python3笔记本
  4. 创建一个单元格并输入下面的代码
  5. 运行单元格
  6. 移动滑块

单元格代码

%gui asyncio

import asyncio
def wait_for_change(widget, value):
    future = asyncio.Future()
    def getvalue(change):
        # make the new value available
        future.set_result(change.new)
        widget.unobserve(getvalue, value)
    widget.observe(getvalue, value)
    return future

from ipywidgets import IntSlider
slider = IntSlider()

async def f():
    for i in range(10):
        print('did work %s'%i)
        #x = await asyncio.sleep(1)
        x = await …
Run Code Online (Sandbox Code Playgroud)

python-asyncio jupyter-notebook ipywidgets jupyter-lab

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

当需要使用AsyncIO和ThreadPoolExecutor时,是否需要手动调用loop.close()?

在 Python文档中,它指出:

应用程序开发人员通常应该使用高级 asyncio 函数,例如 asyncio.run(),并且很少需要引用循环对象或调用其方法。 本节主要面向需要更好地控制事件循环行为的低级代码、库和框架的作者。

当同时使用async和 a 时threadpoolexecutor,如示例代码中所示(来自文档):

import asyncio
import concurrent.futures

def blocking_io():
    # File operations (such as logging) can block the
    # event loop: run them in a thread pool.
    with open('/dev/urandom', 'rb') as f:
        return f.read(100)

async def main():
    loop = asyncio.get_running_loop()

    # 2. Run in a custom thread pool:
    with concurrent.futures.ThreadPoolExecutor() as pool:
        result = await loop.run_in_executor(
            pool, blocking_io)
        print('custom thread pool', result)

asyncio.run(main()) 
Run Code Online (Sandbox Code Playgroud)
  1. 我需要打电话loop.close(),还是会asyncio.run() …

python python-asyncio

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

Python 中的`await` 是否屈服于事件循环?

我想知道当我们await在异步 Python 代码中使用协程时究竟会发生什么,例如:

await send_message(string)
Run Code Online (Sandbox Code Playgroud)

(1)send_message加入事件循环,调用协程放弃对事件循环的控制,或

(2) 我们直接跳进去 send_message

我读到的大多数解释都指向 (1),因为它们将调用协程描述为exiting。但我自己的实验表明(2)是这种情况:我试图在调用者之后但在被调用者之前运行一个协程,但无法实现这一点。

python asynchronous python-3.x async-await python-asyncio

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

如何正确使用asyncio run_coroutine_threadsafe函数?

我试图理解 asyncio 模块并花了大约一小时使用 run_coroutine_threadsafe 函数,我什至来到了工作示例,它按预期工作,但有一些限制。

首先,我不明白应该如何在主(任何其他)线程中正确调用 asyncio 循环,在示例中我调用它并run_until_complete给它一个协程以使其忙于某些事情,直到另一个线程不会给它一个协程。我还有什么其他选择?

在现实生活中,什么情况下我必须混合使用异步和线程(在 Python 中)?据我了解,asyncio 应该取代 Python 中的线程(由于 GIL 不是 IO 操作),如果我错了,请不要生气并分享您的建议。

Python版本为3.7/3.8

import asyncio
import threading
import time


async def coro_func():
    return await asyncio.sleep(3, 42)


def another_thread(_loop):
    coro = coro_func()  # is local thread coroutine which we would like to run in another thread

    # _loop is a loop which was created in another thread

    future = asyncio.run_coroutine_threadsafe(coro, _loop)
    print(f"{threading.current_thread().name}: {future.result()}")
    time.sleep(15)
    print(f"{threading.current_thread().name} is Finished")


if __name__ == '__main__':
    loop = …
Run Code Online (Sandbox Code Playgroud)

python multithreading asynchronous python-3.x python-asyncio

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

如何强行关闭异步生成器?

假设我有一个像这样的异步生成器:

async def event_publisher(connection, queue):
    while True:
        if not await connection.is_disconnected():
            event = await queue.get()
            yield event
        else:
            return
Run Code Online (Sandbox Code Playgroud)

我是这样消费的:

published_events = event_publisher(connection, queue)
async for event in published_events:
    # do event processing here
Run Code Online (Sandbox Code Playgroud)

它工作得很好,但是当连接断开并且没有发布新事件时,async for它将永远等待,所以理想情况下,我想像这样强行关闭生成器:

if connection.is_disconnected():
    await published_events.aclose()
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

RuntimeError: aclose(): asynchronous generator is already running

有没有办法停止处理已经运行的发电机?

python generator python-asyncio

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

ASGI“寿命”协议似乎不受支持

我有一个在 fastapi 和 aiofiles 上运行的异步代码,我正在尝试从 .json 文件加载和保存我的信息,但是每次我关闭程序时,它只保存字典的键并显示“ASGI 'lifespan'协议似乎不受支持”按摩

这是我的开启/关闭部分:

@app.on_event("startup")
async def startup_event():
    global beers
    try:
        async with aiofiles.open("data.json", mode='r+', json=True) as file:
            beers = await file.read()
    except:
        beers = {}


@app.on_event("shutdown")
async def on_exit_app():
    async with aiofiles.open("data.json", "w+") as outfile:
        await outfile.write(beers)
Run Code Online (Sandbox Code Playgroud)

任何想法问题出在哪里?

python python-asyncio python-aiofiles fastapi

8
推荐指数
3
解决办法
3870
查看次数

使用 gevent 执行池的 celery 任务的 SynchronousOnlyOperation

鉴于 celery 使用这些选项运行:

celery -A openwisp2 worker -l info --pool=gevent --concurrency=15 -Ofair
Run Code Online (Sandbox Code Playgroud)

鉴于来自 openwisp-monitoring 的这个celery 任务:

@shared_task
def perform_check(uuid):
    """
    Retrieves check according to the passed UUID
    and calls ``check.perform_check()``
    """
    try:
        check = get_check_model().objects.get(pk=uuid)
    except ObjectDoesNotExist:
        logger.warning(f'The check with uuid {uuid} has been deleted')
        return
    result = check.perform_check()
    if settings.DEBUG:  # pragma: nocover
        print(json.dumps(result, indent=4, sort_keys=True))
Run Code Online (Sandbox Code Playgroud)

大部分时间任务都可以工作,但有时(通常是突发),会生成以下异常:

SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
Run Code Online (Sandbox Code Playgroud)

完整的堆栈跟踪:

SynchronousOnlyOperation: You …
Run Code Online (Sandbox Code Playgroud)

django celery gevent python-asyncio

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

如果不等待异步函数会发生什么?

如果我不使用await调用异步函数,我将返回一个协程。那么,协程会发生什么情况呢?我必须手动执行协程吗?或者这个协程将继续在后台运行?

使用await

async def work():
    result = await stuff()
Run Code Online (Sandbox Code Playgroud)

没有await

async def work():
     result = stuff()
Run Code Online (Sandbox Code Playgroud)

python coroutine async-await python-asyncio

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