C++ में कतारें और पृष्ठभूमि कार्य: बिना दर्द के एसिंक्रोनसी लिखना

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

आपका प्रोग्राम क्यों धीमा चल रहा है, और इसे कैसे ठीक करें

\n\n

कल्पना करें: आपने C++ में एक शानदार पार्सर लिखा है जिसे 10,000 URL एड्रेस प्रोसेस करने हैं। आप इसे चलाते हैं, कॉफी लेने जाते हैं, वापस आते हैं — और यह अभी भी पहली साइट लोड कर रहा है। परिचित लगता है? समस्या यह है कि प्रोग्राम सिंक्रोनस रूप से काम करता है: जब तक एक अनुरोध पूरा नहीं होता, बाकी सोवियत डिपार्टमेंटल स्टोर की तरह अपनी बारी का इंतज़ार करते हैं।

\n\n

आधुनिक दुनिया में उपयोगकर्ता देरी बर्दाश्त नहीं करते। अगर सर्वर 200 ms से अधिक समय लेता है — तो आप ग्राहक खो देते हैं। लेकिन C++ को बिना सब कुछ दोबारा लिखे तेज़ कैसे बनाएं? इसका उत्तर है — कतारें और पृष्ठभूमि कार्य। यह सिर्फ एक फैशनेबल शब्द नहीं है, बल्कि एक मौलिक पैटर्न है जिसका उपयोग Linux कर्नेल, गेम इंजन और उच्च-लोड सेवाओं में किया जाता है।

\n\n

इस लेख में हम समझेंगे कि C++ में कार्य कतारें कैसे काम करती हैं, अपना खुद का सरल thread pool लिखेंगे और डेटा रेस और डेडलॉक के बिना पृष्ठभूमि में डेटा प्रोसेस करना सीखेंगे। अपने कोड को बेहतर बनाने के लिए तैयार हैं? चलिए शुरू करते हैं।

\n\n

कार्य कतार क्या है और इसकी आवश्यकता क्यों है

\n\n

कार्य कतार (task queue) एक डेटा संरचना है जो FIFO (First In, First Out) सिद्धांत पर काम करती है। एक कन्वेयर बेल्ट की कल्पना करें: आप एक छोर पर कार्य जोड़ते हैं, और निष्पादक थ्रेड उन्हें दूसरे छोर से लेते हैं। यह Producer-Consumer (उत्पादक-उपभोक्ता) पैटर्न का आधार है।

\n\n

C++ में इसकी आवश्यकता क्यों है? यहाँ तीन मुख्य कारण हैं:

\n\n
    \n
  • समानांतर प्रसंस्करण — कई थ्रेड एक साथ कतार से कार्य लेते हैं, जिससे काम कई गुना तेज़ हो जाता है।
  • \n
  • एसिंक्रोनसी — मुख्य थ्रेड ब्लॉक नहीं होता, बल्कि नए अनुरोध स्वीकार करता रहता है या इंटरफ़ेस अपडेट करता रहता है।
  • \n
  • लोड बैलेंसिंग — अगर एक कार्य भारी है, तो अन्य थ्रेड हल्के कार्य उठा लेंगे, और सिस्टम हैंग नहीं होगा।
  • \n
\n\n

उदाहरण के लिए, C++ पर एक वेब सर्वर आने वाले HTTP अनुरोधों को कतार में डाल सकता है, और thread pool उन्हें समानांतर रूप से प्रोसेस करता है। जब एक थ्रेड JSON पार्स कर रहा होता है, दूसरा डेटाबेस में लिख रहा होता है — और यह सब मुख्य लूप को ब्लॉक किए बिना होता है।

\n\n

स्क्रैच से C++ में एक सरल कतार लिखना

\n\n

चलिए एक बुनियादी उदाहरण से शुरू करते हैं। C++ की मानक लाइब्रेरी में std::queue है, लेकिन मल्टीथ्रेडिंग के लिए इसे एक सुरक्षित क्लास में लपेटना होगा। यहाँ थ्रेड-सेफ कतार का न्यूनतम कार्यान्वयन है:

\n\n
#include <queue>\n#include <mutex>\n#include <condition_variable>\n#include <functional>\n#include <thread>\n\nclass ThreadSafeQueue {\nprivate:\n    std::queue<std::function<void()>> tasks;\n    std::mutex mtx;\n    std::condition_variable cv;\n\npublic:\n    void push(std::function<void()> task) {\n        std::lock_guard<std::mutex> lock(mtx);\n        tasks.push(task);\n        cv.notify_one();  // एक प्रतीक्षारत थ्रेड को जगाएं\n    }\n\n    std::function<void()> pop() {\n        std::unique_lock<std::mutex> lock(mtx);\n        cv.wait(lock, [this] { return !tasks.empty(); });\n        auto task = tasks.front();\n        tasks.pop();\n        return task;\n    }\n};\n
\n\n

यहाँ हम कतार तक पहुँच की सुरक्षा के लिए std::mutex और std::condition_variable का उपयोग करते हैं ताकि थ्रेड नए कार्यों की प्रतीक्षा में CPU बर्बाद न करें। जब कोई कार्य आता है, तो हम notify_one() से एक थ्रेड को जगाते हैं।

\n\n

लेकिन यह केवल आधा काम है। हमें एक thread pool चाहिए जो इन कार्यों को निष्पादित करेगा।

\n\n

थ्रेड पूल बनाना: पृष्ठभूमि कार्यों का दिल

\n\n

थ्रेड पूल पहले से बनाए गए थ्रेड्स का एक सेट है जो काम की प्रतीक्षा करते हैं। प्रत्येक कार्य के लिए थ्रेड बनाने और नष्ट करने (जो महंगा है) के बजाय, हम उन्हें पुनः उपयोग करते हैं। यहाँ एक क्लासिक कार्यान्वयन है:

\n\n
class ThreadPool {\nprivate:\n    std::vector<std::thread> workers;\n    ThreadSafeQueue queue;\n    bool stop = false;\n\n    void worker_loop() {\n        while (!stop) {\n                

ब्लॉग

पुस्तक अनुशंसाएँ