[Python] AsyncIO how to make use of selectors

Discussão em 'Python' iniciado por Stack, Agosto 18, 2025.

  1. Stack

    Stack Membro Participativo

    AsyncIO uses an event loop to pause and resume methods. For example, you can implement a simple corotine like this

    import types

    @types.coroutine
    def wait(seconds: int) -> None:
    start_time = time.time()

    while time.time() - start_time < seconds:
    yield


    This method will wait at least n seconds. But it is of course possible that it waits more than n seconds, since it will only continue when it is resumed, which will be on the next loop iteration.

    You could do a similar thing if you wanted to create a request and continue once it was successful.

    import socket
    from socket import BlockingIOError

    @types.coroutine
    def request(url: str) -> None:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((url, 80))
    s.send(f'GET / HTTP/1.1\nHost: {url}\n\n'.encode())
    s.setblocking(False)

    response = b''
    while True:
    try:
    data = s.recv(1024)
    response += data
    except BlockingIOError:
    if response:
    break
    yield


    This method will check each iteration to see if data can be retrieved, and if so, continue with the other tasks in the event loop.

    I know that most modern operating systems provide a functionality to select all sockets that are ready. For example in the case of Linux this is epoll (which has a time complexity of O(1)).

    My question now is how to use this with AsyncIO. It would be great to have the functionality to resume execution of the method (generator) only when the socket is really ready.

    I have seen that asyncio exposes some socket methods like socket_connect. But I wasn't been able to find out if this uses selectors under the hood.

    @types.coroutine
    async def request(url: str) -> None:
    loop = asyncio.get_event_loop()
    await loop.sock_connect(url, 80)
    ...

    Continue reading...

Compartilhe esta Página