C++ के लिए कार्य कतारें: कार्यान्वयन और उपयोग

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

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

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

C++ के लिए कार्य कतारें: सिद्धांत से व्यवहार तक



कार्य कतार (task queue) C++ में मल्टीथ्रेड प्रोग्रामिंग के प्रमुख पैटर्न में से एक है। यह डेटा रेस और अत्यधिक संसाधन खपत से बचते हुए, थ्रेड्स के बीच कार्य को कुशलतापूर्वक वितरित करने की अनुमति देता है। इस लेख में, हम प्रदर्शन और सुरक्षा पर ध्यान केंद्रित करते हुए C++ में कार्य कतारें बनाने और उपयोग करने के तरीके पर चर्चा करेंगे।



कार्य कतार की आवश्यकता क्यों है?

आधुनिक अनुप्रयोगों में अक्सर कई छोटे कार्यों को समानांतर रूप से निष्पादित करने की आवश्यकता होती है। प्रत्येक कार्य के लिए सीधे थ्रेड बनाने से ओवरहेड होता है: थ्रेड बनाने में समय और मेमोरी लगती है। कार्य कतार थ्रेड पूल (thread pool) के माध्यम से इस समस्या का समाधान करती है:

  • थ्रेड्स का पुन: उपयोग — कार्य पूरा होने के बाद थ्रेड नष्ट नहीं होते, बल्कि पूल में वापस आ जाते हैं।
  • लोड संतुलन — कार्य समान रूप से वितरित होते हैं।
  • संसाधन प्रबंधन — एक साथ काम करने वाले थ्रेड्स की संख्या को सीमित करना।


C++ में कार्य कतार का मूल कार्यान्वयन

आइए std::queue और म्यूटेक्स का उपयोग करके एक सरल लेकिन थ्रेड-सुरक्षित कार्य कतार देखें। इसके लिए हम C++11 और उससे ऊपर की मानक लाइब्रेरी का उपयोग करेंगे।



#include <queue>#include <mutex>#include <condition_variable>#include <functional>#include <thread>#include <vector>

class TaskQueue {public: using Task = std::function<void()>;

explicit TaskQueue(size_t numThreads) : stop(false) { for (size_t i = 0; i < numThreads; ++i) { workers.emplace_back([this] { workerLoop(); }); } }

~TaskQueue() { { std::unique_lock<std::mutex> lock(mutex); stop = true; } condition.notify_all(); for (auto& worker : workers) { if (worker.joinable()) { worker.join(); } } }

void enqueue(Task task) { { std::unique_lock<std::mutex> lock(mutex); tasks.push(std::move(task)); } condition.notify_one(); }

private: void workerLoop() { while (true) { Task task; { std::unique_lock<std::mutex> lock(mutex); condition.wait(lock, [this] { return stop || !tasks.empty(); }); if (stop && tasks.empty()) { return; } task = std::move(tasks.front()); tasks.pop(); } task(); // कार्य निष्पादन } }

std::queue<Task> tasks; std::mutex mutex; std::condition_variable condition; bool stop; std::vector<std::thread> workers;};


उपयोग का उदाहरण

अब हम दिखाएंगे कि सरल गणनाओं को समानांतर रूप से निष्पादित करने के लिए हमारे TaskQueue वर्ग का उपयोग कैसे करें:



#include <iostream>

int main() { TaskQueue tq(4); // 4 थ्रेड का पूल

for (int i = 0; i < 10; ++i) { tq.enqueue([i] { std::cout << "कार्य " << i << " थ्रेड द्वारा निष्पादित किया गया " << std::this_thread::get_id() << std::endl; }); }

// tq का डिस्ट्रक्टर सभी कार्यों के पूरा होने की प्रतीक्षा करेगा return 0;}


उन्नत सुविधाएँ: प्राथमिकता कतार

कभी-कभी कार्यों को उनके महत्व के क्रम में संसाधित करने की आवश्यकता होती है। इसके लिए सामान्य कतार के बजाय std::priority_queue का उपयोग किया जा सकता है। आइए प्राथमिकताओं के लिए समर्थन जोड़ें:



#include <queue>#include <functional>

class PriorityTaskQueue {public: using Task = std::function<void()>;

struct PrioritizedTask { int priority; Task t

अनुशंसाएँ