Episode ini membedah threading, multiprocessing, dan asyncio beserta model serta jebakan masing-masing. Kalian juga belajar pola async modern dengan asyncio TaskGroups di Python 3.11 serta alternatif seperti trio dan anyio.

Aplikasi yang menangani banyak hal sekaligus adalah kebutuhan nyata. Episode 15 membedah tiga pendekatan concurrency Python: threading, multiprocessing, dan asyncio. Masing-masing punya model, kekuatan, dan jebakan sendiri.
Kita juga mempelajari pola async modern dengan asyncio.TaskGroup di Python 3.11 serta alternatif seperti trio dan anyio. Dengan pemahaman ini, kalian bisa memilih pendekatan yang tepat untuk setiap masalah.
Sebelum memilih alat concurrency, kenali jenis beban kerja:
import time
def io_bound():
time.sleep(1)
def cpu_bound():
total = 0
for i in range(10_000_000):
total += i
return totaltime.sleep(1) meniru beban I/O — menunggu jaringan atau disk. Loop besar meniru beban CPU. I/O-bound cocok dengan threading dan asyncio; CPU-bound cocok dengan multiprocessing. Kesalahan memilih pendekatan membuat aplikasi tidak kencang meski sudah concurrency.
Threading berjalan dalam satu proses dan berbagi memory, tapi dibatasi GIL untuk kode CPU:
import threading
import time
def kerja(nama):
time.sleep(1)
print(f"{nama} selesai")
mulai = time.perf_counter()
t1 = threading.Thread(target=kerja, args=("A",))
t2 = threading.Thread(target=kerja, args=("B",))
t1.start()
t2.start()
t1.join()
t2.join()
print(time.perf_counter() - mulai)threading.Thread(target=kerja, args=("A",)) membuat thread baru. Karena time.sleep melepas GIL, dua thread menyelesaikan tugas bersamaan — total waktu jauh di bawah 2 detik. Untuk I/O-bound, threading efektif.
Multiprocessing memakai proses terpisah, masing-masing punya interpreter sendiri:
from multiprocessing import Pool
def hitung(n):
total = 0
for i in range(n):
total += i
return total
if __name__ == "__main__":
with Pool(4) as pool:
hasil = pool.map(hitung, [10_000_000] * 4)
print(hasil)with Pool(4) as pool: membuat empat proses. pool.map membagi tugas. Berbeda dari thread, proses punya GIL sendiri sehingga komputasi CPU berjalan paralel. Perhatikan guard if __name__ == "__main__" yang wajib untuk multiprocessing di banyak sistem.
asyncio menjalankan banyak tugas dalam satu thread memakai event loop:
import asyncio
async def kerja(nama):
await asyncio.sleep(1)
return f"{nama} selesai"
async def utama():
hasil = await asyncio.gather(
kerja("A"),
kerja("B"),
kerja("C"),
)
print(hasil)
asyncio.run(utama())async def kerja(nama) mendefinisikan coroutine dan await asyncio.sleep(1) menunda tanpa memblokir. asyncio.gather menjalankan banyak coroutine bersamaan. asyncio.run(utama()) memulai event loop. Model ini sangat efisien untuk ribuan koneksi bersamaan.
Python 3.11 memperkenalkan asyncio.TaskGroup untuk mengelola sekelompok tugas secara terstruktur:
import asyncio
async def kerja(nama):
await asyncio.sleep(1)
return f"{nama} selesai"
async def utama():
async with asyncio.TaskGroup() as grup:
tugas = [grup.create_task(kerja(nama)) for nama in ["A", "B", "C"]]
for t in tugas:
print(t.result())
asyncio.run(utama())async with asyncio.TaskGroup() as grup: membuat grup tugas. grup.create_task(...) menambahkan tugas yang dijalankan bersamaan. Blok async with menunggu semua selesai, dan membatalkan semua jika ada satu yang gagal — manajemen error yang jauh lebih baik daripada gather.
anyio menyediakan satu API yang berjalan di atas asyncio maupun trio:
pip install anyioimport anyio
async def kerja(nama):
await anyio.sleep(1)
print(f"{nama} selesai")
async def utama():
async with anyio.create_task_group() as grup:
grup.start_soon(kerja, "A")
grup.start_soon(kerja, "B")
anyio.run(utama)anyio.create_task_group() membuat task group yang bisa dijalankan di backend mana pun. FastAPI dan Starlette memakai anyio, sehingga kalian bisa memilih backend tanpa mengubah API. Ini investasi portabilitas yang baik.
Inti yang harus dibawa pulang:
Di episode 16 selanjutnya kita akan membahas performance tuning dan profiling — profiler seperti cProfile dan pyinstrument, sampling profiler dan flame graph, optimasi hot path, ekstensi native dengan Cython, serta kapan memakai PyPy. Aplikasi kalian akan berjalan jauh lebih cepat!