C++ में एसिंक्रोनस प्रोग्रामिंग का परिचय
आधुनिक एप्लिकेशन तेजी से उच्च प्रदर्शन और प्रतिक्रियाशीलता की मांग करते हैं। C++ में एसिंक्रोनस प्रोग्रामिंग एक शक्तिशाली उपकरण है जो मुख्य निष्पादन थ्रेड को ब्लॉक किए बिना एक साथ कई कार्यों को करने की अनुमति देता है। इस गाइड में, हम C++ में एसिंक्रोनसिटी की मूल बातें समझेंगे: क्लासिकल दृष्टिकोण से लेकर C++20 मानक में जोड़े गए आधुनिक कोरूटीन (coroutines) तक।
यदि आप C++ में नए हैं, लेकिन बुनियादी सिंटैक्स से पहले से परिचित हैं, तो यह लेख आपको यह समझने में मदद करेगा कि अपने प्रोग्राम को एक साथ कई काम कैसे करवाएं। हम व्यावहारिक उदाहरण देखेंगे जिन्हें आप तुरंत अपने प्रोजेक्ट में लागू कर सकते हैं।
मुख्य अवधारणाएं और इसकी आवश्यकता क्यों है
पारंपरिक सिंक्रोनस प्रोग्रामिंग में, कोड सख्ती से क्रमिक रूप से निष्पादित होता है: एक ऑपरेशन पूरा होता है, फिर अगला शुरू होता है। यह सरल है, लेकिन अप्रभावी है यदि प्रोग्राम इनपुट/आउटपुट (फ़ाइल पढ़ना, नेटवर्क अनुरोध) की प्रतीक्षा करता है या भारी गणना करता है।
एसिंक्रोनस प्रोग्रामिंग इस समस्या को हल करती है, जिससे अनुमति मिलती है:
- मुख्य थ्रेड को ब्लॉक न करना — एप्लिकेशन का इंटरफ़ेस प्रतिक्रियाशील बना रहता है।
- निष्पादन को तेज़ करना — मल्टी-कोर प्रोसेसर पर डेटा का समानांतर प्रसंस्करण।
- संसाधनों का कुशलतापूर्वक उपयोग करना — जब एक कार्य डेटा की प्रतीक्षा करता है, दूसरा निष्पादित हो सकता है।
C++ में एसिंक्रोनसिटी को लागू करने के कई तरीके हैं: निम्न-स्तरीय थ्रेड्स (std::thread) से लेकर उच्च-स्तरीय एब्स्ट्रैक्शन (std::async, std::future और कोरूटीन) तक।
1. std::async और std::future के साथ एसिंक्रोनसिटी
C++ में एसिंक्रोनस कार्य शुरू करने का सबसे सरल तरीका हेडर फ़ाइल <future> से फ़ंक्शन std::async का उपयोग करना है। यह एक std::future ऑब्जेक्ट लौटाता है जो निष्पादन का परिणाम संग्रहीत करता है।
बुनियादी उदाहरण
#include <iostream>#include <future>#include <thread>#include <chrono>
// फ़ंक्शन जिसे एसिंक्रोनस रूप से निष्पादित किया जाएगाint slow_calculation(int x) { std::this_thread::sleep_for(std::chrono::seconds(2)); // लंबे काम का अनुकरण return x * x;}
int main() { std::cout << "एसिंक्रोनस कार्य शुरू कर रहे हैं..." << std::endl; // slow_calculation को एक अलग थ्रेड में शुरू करें std::future<int> result = std::async(std::launch::async, slow_calculation, 5); std::cout << "मुख्य थ्रेड काम करता रहता है..." << std::endl; // परिणाम प्राप्त करें (यदि कार्य अभी तक पूरा नहीं हुआ है तो थ्रेड को ब्लॉक करता है) int value = result.get(); std::cout << "परिणाम: " << value << std::endl; // आउटपुट: 25 return 0;}इस उदाहरण में, std::async फ़ंक्शन को एक अलग थ्रेड में शुरू करता है। जब तक यह निष्पादित होता है, मुख्य थ्रेड एक संदेश प्रिंट करता है। विधि get() कार्य के पूरा होने की प्रतीक्षा करती है और परिणाम लौटाती है।
लॉन्च नीतियां
std::async के दो मोड हैं:
std::launch::async— कार्य गारंटी के साथ एक नए थ्रेड में निष्पादित होता है।std::launch::deferred— कार्य आलसी रूप से निष्पादित होता है, केवल उसी थ्रेड मेंget()याwait()कॉल करने पर।
2. Promises और Futures: मैन्युअल प्रबंधन
यदि आपको एसिंक्रोनस कार्यों के अधिक लचीले प्रबंधन की आवश्यकता है, तो std::promise और std::future की जोड़ी का उपयोग करें। promise आपको एक थ्रेड में मान या अपवाद सेट करने की अनुमति देता है, और future इसे दूसरे थ्रेड में प्राप्त करने की अनुमति देता है।
promise के साथ उदाहरण
#include <iostream>#include <future>#include <thread>
void worker(std::promise<int> prom, int a, int b) { try { int result = a / b; // हो सकता है