非同期モデルについて(Python)
| 登録日 | :2025/06/07 13:35 |
|---|---|
| カテゴリ | :Python基礎 |
ピザの注文を受け付けるピザーサーバを題材に並列処理を学ぶ。
asyncioを用いた、非同期処理サーバのサンプルコード
"""
Chapter12 / asynchronous_pizza / aio.py
"""
import asyncio
import socket
import time
class Kitchen:
@staticmethod
def cook_pizza(n):
print(f"Started Cooking {n} pizzas!")
time.sleep(n)
print(f"Fresh {n} pizzas are ready!")
BUFFER_SIZE = 1024
ADDRESS = ('127.0.0.1', 12345)
class Server:
def __init__(self, event_loop: asyncio.AbstractEventLoop) -> None:
self.event_loop = event_loop
print(f"Starting up at: {ADDRESS}")
self.server_soket = socket.create_server(ADDRESS)
self.server_soket.setblocking(False)
async def start(self) -> None:
"""
async:関数が非同期であることを示す
"""
print("Server listening for incoming connections")
try:
while True:
"""
await: コルーチンが完了するのを待つ間、他のタスクができるようにする
"""
conn, client_address = await self.event_loop.sock_accept(
self.server_soket)
self.event_loop.create_task(self.serve(conn))
except Exception:
self.server_soket.close()
print("Server stopped.")
async def serve(self, conn):
while True:
data = await self.event_loop.sock_recv(conn, BUFFER_SIZE)
if not data:
break
try:
order = int(data.decode())
response = f"Thank you for ordering {order} pizzas!¥n"
print(f"Sending messages to {conn.getpeername()}")
await self.event_loop.sock_sendall(conn, f"{response}".encode())
await self.event_loop.run_in_executor(None, Kitchen.cook_pizza, order)
response = f"Your order of {order} pizzas is ready!¥n"
except ValueError:
response = "Wrong number of pizzas, please try again.¥n"
print(f"Sending message to {conn.getpeername()}")
await self.event_loop.sock_sendall(conn, response.encode())
print(f"Connection with {conn.getpeername()} has been closed")
conn.close()
if __name__ == "__main__":
event_loop = asyncio.get_event_loop()
server = Server(event_loop=event_loop)
event_loop.create_task(server.start())
event_loop.run_forever()