2009-05-22 7 views
5

मुझे श्रमिकों (धागे के रूप में प्रतिनिधित्व) और (एकाधिक) कतारों की एक प्रणाली बनाने की आवश्यकता है। व्यक्तिगत नौकरियां कतारों में से एक में प्रतीक्षा कर रही हैं और कार्यकर्ता धागे को संसाधित करने की प्रतीक्षा कर रही हैं। प्रत्येक कार्यकर्ता केवल कुछ कतारों से ही नौकरियों को संसाधित कर सकता है। कोई स्पिन-प्रतीक्षा नहीं। सी/सी ++, pthreads, मानक POSIX।सी ++ - धागे और एकाधिक कतार

मेरे लिए समस्या "एकाधिक कतार" चीज है। मुझे पता है कि इसे एक कतार के साथ कैसे कार्यान्वित किया जाए। श्रमिकों को उन सभी कतारों पर इंतजार करना पड़ता है जिन्हें वे संसाधित कर सकते हैं (उनमें से किसी के लिए प्रतीक्षा करें)।

विंडोज़ पर मैं WaitForMultipleObjects का उपयोग करूंगा, लेकिन इसे बहु-मंच होना चाहिए।

मुझे इसके लिए कोई विशेष कोड नहीं चाहिए, केवल एक संकेत या मॉडल का विवरण जो मुझे उपयोग करना चाहिए। अग्रिम में धन्यवाद।

+0

क्या आप बूस्ट का उपयोग कर सकते हैं? – PiNoYBoY82

उत्तर

4

आप क्या कर सकते हैं condition variable का उपयोग करें। अपने कार्यकर्ता धागे को एक शर्त चर पर प्रतीक्षा करें। जब कोई नौकरी किसी भी नौकरी कतार में जोड़ा जाता है, तो स्थिति परिवर्तक को सिग्नल करें। फिर, जब कार्यकर्ता धागा उठता है, तो यह उस कतार की जांच करता है जिस पर वह इंतजार कर रहा है। अगर उनमें से कोई नौकरी है, तो यह उस कतार को बंद कर देता है। अन्यथा, यह स्थिति चर पर प्रतीक्षा करने के लिए वापस चला जाता है। एक कंडीशन वैरिएबल पर प्रतीक्षा करने से थ्रेड सो जाता है, इसलिए यह CPU समय का उपभोग नहीं करता है।

बेशक, यह बिना कहने के चला जाता है कि आपको नौकरी के साथ नौकरी कतारों में सभी पहुंचों की रक्षा करनी चाहिए (उदा। pthread_mutex_t)।

+0

अच्छा विचार है, लेकिन यह एक खाली कतार में नौकरी जोड़ने के दौरान सभी कार्यकर्ता धागे जाग जाएगा। मुझे लगता है कि मैं इसे वैसे भी करूँगा, लेकिन क्या केवल "सही" थ्रेड (और आदर्श रूप से केवल सही धागे में से एक) जागने का कोई तरीका है? –

+0

pthread_cond_signal() हालत चर पर प्रतीक्षा करने वाले "कम से कम एक" थ्रेड को जगाएगा, जबकि pthread_cond_broadcast() सभी धागे को जगाएगा। सिद्धांत रूप में, pthread_cond_signal() केवल अधिकांश समय में एक धागे को जागृत करना चाहिए, लेकिन मुझे नहीं पता कि यह सच है या नहीं। –

+0

लेकिन आपके समाधान में * सभी थ्रेड उठाने के लिए * की आवश्यकता है, क्योंकि नौकरी एक कतार में हो सकती है कि * एक * कार्यकर्ता संसाधित नहीं करता है। –

1

यदि प्रत्येक कतार के लिए बहुत से कर्मचारी नहीं हैं, तो आप प्रत्येक कार्यकर्ता के लिए एक शर्त चर बना सकते हैं।

0

मैं जो करना चाहता हूं वह डेटा को कतारबद्ध करने के लिए बूस्ट :: एएसओ का उपयोग करता है ताकि आपके एकाधिक धागे इसमें जा सकें। आप पोस्ट कमांड के माध्यम से कतार में एक रेफरी पास कर सकते हैं और तदनुसार थ्रेड प्रक्रिया कर सकते हैं।

0

प्रत्येक कतार के लिए अलग लॉक रखने के बजाय, सभी कतारों के लिए एक लॉक क्यों नहीं है? ताला

  • पर

    1. प्रतीक्षा ताला
    2. विपंक्ति जाओ जो भी कतार
    3. रिलीज ताला
    4. प्रक्रिया dequeued आइटम
    5. गोटो कदम 1

    यह मानते हुए कि से डेक्यू नगण्य समय लेता है (इसलिए लॉक केवल नगण्य समय के लिए आयोजित होता है) वहां एक से अधिक ताला की आवश्यकता नहीं हो सकती है।

  • +0

    मुझे नहीं लगता कि यह काम करेगा। एक कार्यकर्ता केवल एक विशिष्ट कतार से नौकरियों को संसाधित करता है। यदि "खराब" कतार में एकमात्र नौकरी है, तो कर्मचारी कार्यरत रहेंगे जब तक कि अन्य कार्यकर्ता नौकरी न ले ले। –

    0

    आप ऐसा कुछ कर सकते हैं: प्रत्येक नौकरी में "कतार" होता है। उदाहरण:

    कहें कि आपके पास 2 कतार हैं। आपकी नौकरियां कह सकती हैं:

    job[0].queue = 1; /* That job is in queue 1 */ 
    job[1].queue = 1; 
    job[2].queue = 2; /* this job is in queue 2 */ 
    ... 
    etc 
    

    तो फिर आपके पास "धागे का थैला" है। एक थ्रेड बस नौकरी चुनता है - कहो, नौकरी [2]। यदि उस धागे को केवल कतार 1 से नौकरियों को संसाधित करने की अनुमति है, तो यह उस नौकरी को तैयार कतार में वापस रखता है और एक अलग नौकरी चुनता है।

    तो प्रत्येक थ्रेड जानता है कि कौन सी कतारों को संसाधित करने की अनुमति है, और जब यह नौकरी चुनता है, तो यह सुनिश्चित करता है कि नौकरी की "कतार" फ़ील्ड मेल खाती है। यदि ऐसा नहीं होता है, तो यह एक अलग नौकरी चुनता है।

    (यह कई तरीकों से है कि कैसे प्रक्रिया शेड्यूलिंग एकाधिक कोर पर लिनक्स में काम करती है। प्रत्येक प्रक्रिया में बिटमैस्क होता है कि यह प्रोसेसर को चलाने की अनुमति है, और फिर प्रोसेसर यह सुनिश्चित करता है कि यह उस प्रक्रिया को चलाने के लिए "अनुमति" है ऐसा करने से पहले)

    5

    कैसे के बारे में:।

    • सभी कार्यकर्ता धागे एक सेमाफोर पर इंतजार
    • जब कुछ भी कतार में जोड़ा जाता है, सेमाफोर वृद्धि की जाती है, जो किसी एकल थ्रेड उठता
    • थ्रेड चेक ks कतारों यह में रुचि रखता है, उनमें से एक संसाधित करता है और

    आप अतिरिक्त म्युटेक्स (ते) की आवश्यकता होगी सेमाफोर पर इंतजार कर वापस चला जाता है & कतारों को लिखते वास्तविक पढ़ नियंत्रित करने के लिए।

    +1

    +1 मैं इस पर नील के साथ जाऊंगा :) – ralphtheninja

    0

    मैं हाल ही में इस बारे में सोच रहा हूं और एकमात्र विचार जो मैं आ सकता हूं (यह मानते हुए कि आपके पास थ्रेड-सुरक्षित कतार हैं) केवल एक ही कतार की सेवा करने वाले कई धागे हैं।

    इसके बाद आप एक या एक से अधिक काम कर रहे थ्रेड को एक कतार में नौकरियां जोड़ सकते हैं और एक या अधिक कार्यकर्ता धागे कतार पर अवरुद्ध कर सकते हैं जब तक उन्हें प्रक्रिया करने के लिए कुछ न मिल जाए।

    यदि आपके पास कभी-कभी कई कतार हैं जो एकाधिक कार्यकर्ता धागे को मतदान करना है, तो एक समाधान प्रत्येक कतार और अतिरिक्त कतार के लिए एक अतिरिक्त धागा जोड़ना हो सकता है। प्रत्येक ब्लॉक को अपनी एकल कतार पर अतिरिक्त थ्रेड, लेकिन अतिरिक्त कतार में नौकरियों को आगे बढ़ाएं। अब मौजूदा वर्कर थ्रेड एक कतार पर अवरुद्ध करने के लिए वापस आ गया है।