Go में कार्य कतारें: एक व्यावहारिक मार्गदर्शिका

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

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

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

परिचय: Go में कार्य कतारों की आवश्यकता क्यों?

\n

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

\n

Go भाषा (Golang) कार्य कतारों को लागू करने के लिए अंतर्निहित तंत्र प्रदान करती है: गोरूटीन (goroutines) और चैनल (channels)। इस लेख में, हम व्यावहारिक रूप से समझेंगे कि बाहरी मैसेज ब्रोकर (हालांकि प्रोडक्शन में RabbitMQ या Redis उपयोगी हो सकते हैं) का सहारा लिए बिना, Go की मानक लाइब्रेरी का उपयोग करके एक विश्वसनीय कार्य कतार कैसे बनाई जाए।

\n\n

मुख्य भाग

\n\n

1. मूल वर्कर पूल पैटर्न

\n

वर्कर पूल गोरूटीन (वर्कर) का एक निश्चित संख्या का सेट है जो एक चैनल को सुनते हैं और आने वाले कार्यों को संसाधित करते हैं। यह समांतरता की डिग्री को नियंत्रित करने और सिस्टम ओवरलोड से बचने की अनुमति देता है।

\n

एक सरल उदाहरण पर विचार करें: हम 3 वर्कर का एक पूल बनाते हैं जो पूर्णांकों को संसाधित करते हैं (कार्य का अनुकरण)।

\n
package main\n\nimport (\n    "fmt"\n    "sync"\n    "time"\n)\n\nfunc worker(id int, jobs <-chan int, wg *sync.WaitGroup) {\n    defer wg.Done()\n    for job := range jobs {\n        fmt.Printf("वर्कर %d ने कार्य %d शुरू किया\\n", id, job)\n        time.Sleep(time.Second) // कार्य का अनुकरण\n        fmt.Printf("वर्कर %d ने कार्य %d पूरा किया\\n", id, job)\n    }\n}\n\nfunc main() {\n    const numJobs = 5\n    const numWorkers = 3\n\n    jobs := make(chan int, numJobs)\n    var wg sync.WaitGroup\n\n    // वर्कर शुरू करें\n    for w := 1; w <= numWorkers; w++ {\n        wg.Add(1)\n        go worker(w, jobs, &wg)\n    }\n\n    // कार्य भेजें\n    for j := 1; j <= numJobs; j++ {\n        jobs <- j\n    }\n    close(jobs) // वर्कर को समाप्त करने के लिए चैनल बंद करें\n\n    wg.Wait()\n    fmt.Println("सभी कार्य पूर्ण हुए")\n}
\n

कोड का विश्लेषण:

\n
    \n
  • jobs — एक बफ़रयुक्त चैनल है जिसमें हम कार्य भेजते हैं।
  • \n
  • worker — एक फ़ंक्शन है जो चैनल से पढ़ता है और प्रत्येक कार्य को संसाधित करता है।
  • \n
  • sync.WaitGroup — सभी वर्कर के पूरा होने की प्रतीक्षा करता है।
  • \n
  • सभी कार्य भेजने के बाद, चैनल बंद कर दिया जाता है (close(jobs)), जिससे वर्कर में for range लूप समाप्त हो जाता है।
  • \n
\n

यह पैटर्न अधिक जटिल समाधानों का आधार है।

\n\n

2. प्राथमिकता और टाइमआउट के साथ कतार

\n

वास्तविक एप्लिकेशन में, कार्यों की अलग-अलग प्राथमिकता हो सकती है या उन्हें एक निश्चित समय के भीतर निष्पादित करने की आवश्यकता हो सकती है। आइए एक कतार लागू करें जहां प्राथमिकता वाले कार्य पहले संसाधित होते हैं, और लंबे कार्यों को रद्द करने के लिए टाइमआउट के साथ एक संदर्भ जोड़ें।

\n
package main\n\nimport (\n    "context"\n    "fmt"\n    "time"\n)\n\ntype Task struct {\n    ID       int\n    Priority int // संख्या जितनी छोटी, प्राथमिकता उतनी अधिक\n    Data     string\n}\n\nfunc processTask(ctx context.Context, task Task) error {\n    select {\n    case <-ctx.Done():\n        return ctx.Err()\n    case <-time.After(time.Duration(task.Priority) * 500 * time.Millisecond):\n        fmt.Printf("कार्य %d संसाधित: %s (प्राथमिकता %d)\\n", task.ID, task.Data, task.Priority)\n        return nil\n    }\n}\n\nfunc main() {\n    tasks := []Task{\n        {ID: 1, Priority: 3, Data: "निम्न प्राथमिकता"},\n        {ID: 2, Priority: 1, Data: "उच्च प्राथमिकता"},\n        {ID: 3, Priority: 2, Data: "मध्यम प्राथमिकता"},\n    }\n\n    // प्राथमिकता के अनुसार क्रमबद्ध करें (सबसे अधिक प्राथमिकता पहले)\n    // वास्तविक प्रोजेक्ट में सॉर्टिंग या हीप (container/heap) का उपयोग करें\n    for i := 0; i < len(tasks); i++ {\n        for j := i + 1; j < len(tasks); j++ {\n            if tasks[j].Priority < tasks[i].Priority {\n                tasks[i], tasks[j] = tasks[j], tasks[i]\n            }\n                

ब्लॉग

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