Asynkron programmering
Kunna skriva async-kod med asyncio och förstå när samtidighet lönar sig — som i ett API som anropar en LLM.
Förkunskaper
Intuition
Ett API som anropar en LLM väntar 2 sekunder per svar — och gör ingenting under tiden. Med asynkron kod lämnar funktionen ifrån sig kontrollen medan den väntar (await), så att andra förfrågningar kan betjänas. En tråd, tusentals väntande anrop.
Det hjälper när flaskhalsen är väntan (nätverk, disk, databas). Det hjälper inte när flaskhalsen är beräkning (matrismultiplikation) — då behövs processer eller GPU.
Regler: en async def måste await:as; blockerande anrop (time.sleep, requests.get) inuti async fryser allt — använd asyncio.sleep, httpx.AsyncClient. Begränsa samtidighet (semafor) så att du inte skickar 10 000 anrop på en gång.
Kod
import asyncio, time, httpx
async def fraga_llm(client, sem, prompt):
async with sem: # max N samtidiga
r = await client.post(URL, json={"prompt": prompt}, timeout=30)
r.raise_for_status()
return r.json()["text"]
async def main(prompts):
sem = asyncio.Semaphore(8)
async with httpx.AsyncClient() as client:
t = time.perf_counter()
svar = await asyncio.gather(*(fraga_llm(client, sem, p) for p in prompts), return_exceptions=True)
print(f"{len(prompts)} anrop på {time.perf_counter() - t:.1f} s")
return svar
asyncio.run(main(["hej"] * 40)) # ~10 s med 8 samtidiga à 2 s, i stället för 80 s
return_exceptions=True gör att ett fel inte fäller alla — du får undantaget som värde och kan hantera det per prompt.
Behärskning innebär
- Skriver async-funktioner och kör dem samtidigt med gather
- Förklarar när asynkront lönar sig (I/O-bundet) och inte (CPU-bundet)
- Begränsar samtidighet med semafor och hanterar timeout
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- Python — asyncio (PSF) — PSF
- httpx — dokumentation (BSD-3) — BSD-3-Clause