Python Async বনাম Threads: কখন asyncio ব্যবহার করবেন

Backend2026-09-11TryQuickToolBox

Python-এ Concurrency কেন গুরুত্বপূর্ণ

আপনার একটি Python স্ক্রিপ্ট আছে যা একাধিক API থেকে ডেটা আনে। এটি কাজ করে, কিন্তু ধীর—প্রতিটি রিকোয়েস্ট আগেরটি শেষ হওয়ার জন্য অপেক্ষা করে। আপনি asyncio এবং threads সম্পর্কে শুনেছেন, কিন্তু কোনটি ব্যবহার করবেন? ভুল মডেল বেছে নিলে কোড হয় অপ্রয়োজনীয়ভাবে জটিল বা বেদনাদায়কভাবে ধীর হয়ে যেতে পারে।

এই গাইডটি বিভ্রান্তি দূর করবে। আমরা Python-এর async এবং threading মডেল তুলনা করব, দেখাবো ঠিক কখন কোনটি ব্যবহার করবেন, এবং ব্যবহারিক উদাহরণ দেব যা আপনি আপনার নিজের প্রকল্পে প্রয়োগ করতে পারেন।

Python-এর Concurrency ল্যান্ডস্কেপ বোঝা

Python তিনটি প্রধান concurrency মডেল অফার করে:

GIL হল একটি mutex যা একাধিক থ্রেডকে একসাথে Python বাইটকোড চালানো থেকে বিরত রাখে। এর মানে হল থ্রেড CPU-বাউন্ড কাজ দ্রুত করে না, কিন্তু I/O-বাউন্ড কাজে সাহায্য করে কারণ I/O অপারেশনের সময় GIL ছেড়ে দেওয়া হয়।

কখন asyncio ব্যবহার করবেন

asyncio তখন দুর্দান্ত যখন আপনার প্রোগ্রাম বেশিরভাগ সময় বাইরের ইভেন্টের জন্য অপেক্ষা করে: নেটওয়ার্ক রিকোয়েস্ট, ফাইল I/O, ডেটাবেস কোয়েরি, বা টাইমার। যেহেতু এটি একক থ্রেড ব্যবহার করে, আপনি থ্রেড তৈরি এবং কনটেক্সট সুইচিংয়ের ওভারহেড এড়াতে পারেন। ইভেন্ট লুপ হাজার হাজার concurrent সংযোগ দক্ষতার সাথে পরিচালনা করে।

asyncio ব্যবহার করুন যখন:

এখানে একটি সাধারণ উদাহরণ যা একসাথে একাধিক URL আনে:

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    urls = [
        'https://example.com',
        'https://example.org',
        'https://example.net',
    ]
    tasks = [fetch(url) for url in urls]
    results = await asyncio.gather(*tasks)
    print(f'Fetched {len(results)} pages')

asyncio.run(main())

কখন Threads ব্যবহার করবেন

Threads তখন ভালো যখন আপনার blocking I/O অপারেশন থাকে যার async সমতুল্য নেই, বা যখন আপনি legacy কোড নিয়ে কাজ করছেন যা async-বান্ধব নয়। এছাড়াও অল্প সংখ্যক কাজের জন্য এগুলি বোঝা সহজ।

Threads ব্যবহার করুন যখন:

concurrent.futures.ThreadPoolExecutor ব্যবহার করে উদাহরণ:

from concurrent.futures import ThreadPoolExecutor
import requests

def fetch(url):
    response = requests.get(url)
    return response.text

urls = [
    'https://example.com',
    'https://example.org',
    'https://example.net',
]

with ThreadPoolExecutor(max_workers=10) as executor:
    results = list(executor.map(fetch, urls))

print(f'Fetched {len(results)} pages')

asyncio এবং Threads তুলনা

সিদ্ধান্ত নিতে সাহায্য করার জন্য এখানে একটি পাশাপাশি তুলনা:

দিক asyncio Threads
Concurrency মডেল একক-থ্রেডেড ইভেন্ট লুপ একাধিক OS থ্রেড
সেরা জন্য I/O-বাউন্ড, উচ্চ concurrency I/O-বাউন্ড, blocking কল
CPU-বাউন্ড পারফরম্যান্স দুর্বল (GIL) দুর্বল (GIL)
স্কেলেবিলিটি হাজার হাজার কাজ শত শত থ্রেড
জটিলতা async/await সিনট্যাক্স প্রয়োজন পরিচিত synchronous স্টাইল
ডিবাগিং ট্রেসব্যাক সহ কঠিন হতে পারে স্ট্যান্ডার্ড ডিবাগিং টুল
ইকোসিস্টেম ক্রমবর্ধমান async সমর্থন সর্বজনীন

CPU-বাউন্ড কাজ সম্পর্কে কী?

GIL-এর কারণে asyncio বা threads কোনটিই Python-এ CPU-নিবিড় কাজ সমান্তরাল করতে সাহায্য করবে না। CPU-বাউন্ড কাজের জন্য—যেমন সংখ্যা গণনা, ইমেজ প্রসেসিং, বা ডেটা কম্প্রেশন—multiprocessing বা concurrent.futures.ProcessPoolExecutor ব্যবহার করুন।

উদাহরণ:

from concurrent.futures import ProcessPoolExecutor

def cpu_heavy(n):
    return sum(i * i for i in range(n))

if __name__ == '__main__':
    with ProcessPoolExecutor() as executor:
        results = list(executor.map(cpu_heavy, [10**6, 10**6, 10**6]))
    print(results)

সেরা অনুশীলন এবং সমস্যা

সচরাচর জিজ্ঞাসা

আমি কি asyncio এবং threads একসাথে ব্যবহার করতে পারি?

হ্যাঁ। আপনি asyncio.to_thread() বা loop.run_in_executor() ব্যবহার করে থ্রেড পুলে blocking কোড চালাতে পারেন। এটি উপকারী যখন আপনি async কোড থেকে একটি synchronous লাইব্রেরি কল করতে চান ইভেন্ট লুপ ব্লক না করে।

asyncio কি GIL-এর সাথে কাজ করে?

হ্যাঁ, asyncio একটি একক থ্রেডে চলে এবং GIL-এর অধীন। তবে, যেহেতু এটি I/O-বাউন্ড কাজের জন্য ডিজাইন করা হয়েছে, I/O অপারেশনের সময় GIL ছেড়ে দেওয়া হয়, ফলে অন্য কাজগুলি চলতে পারে। CPU-বাউন্ড কাজের জন্য, asyncio কোন গতি বৃদ্ধি দেয় না।

কোনটি দ্রুত: asyncio নাকি threads?

অনেক concurrent অপারেশন সহ I/O-বাউন্ড কাজের জন্য, asyncio সাধারণত দ্রুত এবং আরও স্কেলেবল কারণ এটি থ্রেড ওভারহেড এড়ায়। অল্প সংখ্যক blocking কাজের জন্য, threads সহজ হতে পারে এবং একইভাবে পারফর্ম করে। কোনটিই CPU-বাউন্ড কাজে সাহায্য করে না।

সঠিক পছন্দ করা

আপনার বাধা I/O না CPU তা চিহ্নিত করে শুরু করুন। যদি এটি I/O হয় এবং আপনার উচ্চ concurrency প্রয়োজন, asyncio ব্যবহার করুন। যদি এটি I/O হয় কিন্তু আপনি blocking লাইব্রেরি বা সাধারণ স্ক্রিপ্ট নিয়ে কাজ করছেন, threads একটি শক্ত পছন্দ। CPU-বাউন্ড কাজের জন্য, multiprocessing ব্যবহার করুন।

মনে রাখবেন যে আপনি প্রায়শই এই মডেলগুলি একত্রিত করতে পারেন—উদাহরণস্বরূপ, নেটওয়ার্ক অপারেশনের জন্য asyncio এবং ফাইল I/O-এর জন্য একটি থ্রেড পুল ব্যবহার করা। মূল বিষয় হল ট্রেড-অফগুলি বোঝা এবং আপনার নির্দিষ্ট সমস্যার সাথে মানানসই টুল বেছে নেওয়া।

যখন আপনার concurrent API কল থেকে ফেরত JSON ডেটা দ্রুত ফরম্যাট বা যাচাই করতে হবে, আমাদের JSON Formatter চেষ্টা করুন সহজে pretty-print এবং ডিবাগ করার জন্য।