spitfire-sidra / myapollo-issues

#utterances
0 stars 0 forks source link

blog/asyncio-multi-process/ #16

Open utterances-bot opened 3 months ago

utterances-bot commented 3 months ago

用 Python 學網路程式設計重要概念 — 從 asyncio 到 asyncio 混搭 Multi-process - MyApollo

「 asyncio 就是快」應該是許多人對於 Python asyncio 的認知,但實際上 asyncio 就跟眾多技術一樣並不完美,它也有不擅長以及適合它的應用場景,認識這些它的缺點與優點將可以讓你在不同的應用場景上做出正確的技術決策。 本文將使用 asyncio 高階函式帶大家體驗用 asyncio 開發網

https://myapollo.com.tw/blog/asyncio-multi-process/

KuanJuChenHermanChen commented 3 months ago

用 asyncio 搭配 multi-process,提供另一個作法

import os
import asyncio
import multiprocessing
import socket
from datetime import datetime

data = b"<h1>Hello, World!</h1>" * 10000

async def handle_request(reader: asyncio.streams.StreamReader, writer: asyncio.streams.StreamWriter):
    print(f"[{datetime.now()}] Handling request in process [PID {os.getpid()}]")

    response = (
        b"HTTP/1.1 200 OK\r\n"
        b"Content-Type: text/html\r\n\r\n"
        b"<html>"
        b"<head><title>Example</title></head><body>"
        + data +
        b"</body></html>\r\n"
    )
    writer.write(response)
    await writer.drain()

    writer.close()
    await writer.wait_closed()

async def start_server(sock):
    server = await asyncio.start_server(handle_request, sock=sock)
    addr = server.sockets[0].getsockname()
    print(f"[PID {os.getpid()}] Serving on {addr}")

    async with server:
        await server.serve_forever()

def run_server(sock):
    asyncio.run(start_server(sock))

def main():
    HOST, PORT = "0.0.0.0", 65432
    num_processes = 4

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind((HOST, PORT))
        sock.listen(1000)
        sock.setblocking(False)

        processes: list[multiprocessing.Process] = []
        for _ in range(num_processes):
            p = multiprocessing.Process(target=run_server, args=(sock,))
            p.start()
            processes.append(p)

        for p in processes:
            p.join()

if __name__ == "__main__":
    main()
spitfire-sidra commented 3 months ago

@KuanJuChenHermanChen 謝謝,已補充至內文 👍