थ्रेड्स की बजाय async/await क्यों चुनें?
संकल्पनात्मक मॉडल: threads, async/await, fibers
- कई लोग इनमें अंतर करते हैं:
- Threads = OS‑scheduled, preemptive, parallelism.
- Async/await = stackless coroutines and futures; cooperative concurrency.
- Fibers/green threads = stackful user‑mode threads; look like blocking code but cooperatively scheduled.
- कुछ लोग कहते हैं कि बेहतर तुलना async/await बनाम fibers है, क्योंकि दोनों कुछ OS threads पर I/O को multiplex करते हैं।
- अन्य लोग ध्यान दिलाते हैं कि async/await “बस” CPS/state machines with sugar है; वही underlying I/O primitives।
Cancellation and cleanup
- एक प्रमुख विषय: cancellation semantics.
- Async Rust में आम तौर पर futures को drop करके “cancel” किया जाता है, जिससे operations अचानक रुक सकती हैं, उन्हें प्रतिक्रिया देने का मौका नहीं मिलता, और subtle bugs तथा resource leaks हो सकते हैं।
- Fiber models अक्सर explicit cancellation signals और yield/IO points पर cooperative handling का उपयोग करते हैं, जिससे tasks को cleanup करने, critical sections पूरा करने, या cancellation को ignore करने का मौका मिलता है।
- Rust में Async Drop को desirable माना जाता है, लेकिन तकनीकी रूप से कठिन; कुछ लोग इसे explicit cancellation signals से strictly weaker मानते हैं।
Composability and “function coloring”
- Async को “viral” कहा जाता है: एक बार कोई function async हो जाए, तो callers को भी async होना पड़ता है, जिससे APIs sync vs async flavors में बँट जाती हैं और आगे runtime flavors (Tokio, async‑std, etc.) में भी विभाजन हो जाता है।
- इसकी तुलना fibers/threads से की जाती है, जहाँ concurrency internal detail हो सकती है और public APIs synchronous बने रह सकते हैं।
- कुछ लोग
awaitmarkers को helpful explicit suspension points मानते हैं; अन्य इन्हें noise मानते हैं जो “जहाँ I/O होता है” या वास्तविक interference points से अच्छी तरह मेल नहीं खाते।
Performance, memory, and scalability
- Pro‑async points:
- OS threads की तुलना में प्रति task बहुत कम memory (बड़े stacks नहीं), जिससे लाखों concurrent tasks संभव होते हैं।
- कम kernel context‑switch overhead; high‑concurrency servers और embedded targets, जहाँ threads या OS नहीं हैं, के लिए अच्छा।
- Compiler‑generated state machines कुछ workloads में dynamic allocation से बच सकती हैं और बहुत कम latency दे सकती हैं।
- Skeptical views:
- कई real‑world servers में cache misses और I/O dominate करते हैं; async micro‑optimizations का खास असर नहीं हो सकता।
- Thread‑per‑client खराब है, लेकिन user‑mode green threads या evented I/O के साथ processes भी समान लाभ सरल semantics के साथ दे सकते हैं।
- Async backpressure और cancellation के बारे में reasoning को कठिन बना सकता है, और “stuck” tasks को debug करना मुश्किल है।
FFI, runtimes, and ecosystem fragmentation
- Fibers और M:N threading FFI को जटिल बनाते हैं: TLS, stack growth, और OS threads के बारे में assumptions अक्सर C libraries में टूट जाती हैं।
- Async Rust के executor‑driven futures इनमें से कुछ समस्याएँ avoid करते हैं, लेकिन fragmentation पैदा करते हैं:
- Sync vs async crates; और async crates के बीच भी specific executors पर निर्भरता।
- ऐसी libraries लिखना कठिन है जो executor‑agnostic हों और sync तथा async दोनों worlds के साथ composable हों।
Single‑threaded vs multi‑threaded async
- Single‑thread event loops (Node, many embedded runtimes) data races से बचाते हैं, लेकिन logical races फिर भी रहती हैं; shared state के लिए synchronization फिर भी चाहिए।
- Rust का default async ecosystem (जैसे, Tokio) multi‑threaded है; कई लोग इसे async complexity को full multithreading complexity के साथ जोड़ना मानते हैं।
- कुछ लोग चाहते हैं कि default single‑threaded होता, और multithreaded executors के लिए explicit opt‑in होता।
Use cases and ergonomics
- Async/await की प्रशंसा इस वजह से की जाती है कि यह:
- High‑concurrency I/O services (web servers, proxies) के लिए अच्छा है।
- Embedded और bare‑metal systems, जहाँ OS threads नहीं होते, के लिए उपयोगी है।
- GUI और “single‑threaded but responsive” contexts में अच्छा काम करता है।
- अन्य लोग पसंद करते हैं:
- CPU‑bound work और actor‑style architectures के लिए threads या green threads।
- robustness और सरल mental models के लिए processes plus message passing।
- कई comments शिकायत करते हैं कि Rust में async/await I/O libraries पर हावी है, जिससे threads या processes पर्याप्त होने पर भी यह मजबूरी बन जाता है।
Overall sentiment
- मजबूत विभाजन:
- Enthusiasts async/await को एक शक्तिशाली, expressive concurrency tool मानते हैं जो threads से बेहतर scale करता है और no‑OS environments में काम करता है।
- Critics इसे ergonomically awkward, ecosystem‑splitting, hard to cancel and debug, और अक्सर over‑optimization मानते हैं, जहाँ सरल thread‑ या process‑based designs पर्याप्त होते।