2011-02-24 29 views
9

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

एक और धागा होगा जो कतार से लॉग डेटा पढ़ता है और फ़ाइल में लॉग जानकारी को सहेजने के लिए कुछ जानकारी के साथ इसका उपयोग करता है। असल में यहां हम कई निर्माता एकल उपभोक्ता प्रतिमान लागू कर रहे हैं।

शरीर के किसी भी मुझे सुझाव सकते हैं कि कैसे सी में इस लागू करने के लिए ++ या सी #।

धन्यवाद,

उत्तर

8

बात इस तरह की का उपयोग कर BlockingCollection<T>System.Collections.Concurrent में परिभाषित करने के लिए बहुत आसान है:

यहाँ अवधारणा पर एक अच्छा लेख है।

BlockingCollection<LogRecord> LogQueue = new BlockingCollection<LogRecord>(); 

प्रत्येक निर्माता कतार में आइटम जोड़ता है::

while (!Shutdown) 
{ 
    LogRecord rec = CreateLogRecord(); // however that's done 
    LogQueue.Add(rec); 
} 

और उपभोक्ता कुछ ऐसा ही:

मूल रूप से, आप ताकि सभी धागे उस तक पहुँच सकते आपके कतार बना

while (!Shutdown) 
{ 
    LogRecord rec = LogQueue.Take(); 
    // process the record 
} 

डिफ़ॉल्ट रूप से, BlockingCollectionConcurrentQueue<T> का उपयोग करता है वह बैकिंग स्टोर। ConcurrentQueue थ्रेड सिंक्रनाइज़ेशन का ख्याल रखता है और BlockingCollection किसी आइटम को लेने का प्रयास करते समय एक व्यस्त प्रतीक्षा करता है। यही है, अगर कतार में कोई आइटम नहीं होने पर उपभोक्ता Take पर कॉल करता है, तो यह एक आइटम उपलब्ध होने तक एक व्यस्त व्यस्त प्रतीक्षा (कोई नींद/कताई नहीं) करता है।

+0

हो सकता है कि यह ऑनस्यूमर के लिए अतिरिक्त स्थिति प्राप्त करने के लिए उपयोगी होगा '! (शटडाउन || LogQueue। ())' (यह नहीं पता कि यह कैसे सी # में व्यक्त किया गया है)।या, अगर LogQueue को रोकने का कोई तरीका है, तो केवल इसका उपयोग करें। – glglgl

+1

आपके पास निर्माता कॉल 'CompleteAdding' हो सकता है, जो संग्रह को जोड़ने के लिए पूर्ण रूप से चिह्नित करेगा (यानी कोई और आइटम जोड़ा जा सकता है)। उपभोक्ता तब 'का उपयोग कर सकता है (LogQueue.TryTake (आउट रिक, टाइमआउट। अनंत)), जिसका अर्थ है कि यह संग्रह खाली कर देगा और फिर बाहर निकल जाएगा। अगर संग्रह जोड़ने के लिए पूरा हो गया है और कतार खाली है तो 'TryTake'' गलत 'वापस आ जाएगा। –

+0

@JimMischel उपभोक्ता एक आइटम को हटाने के बाद, कुछ प्रसंस्करण करें, आप कॉलिंग प्रक्रिया के परिणाम कैसे वापस कर सकते हैं? – gdp

2

आप उपयोग कर सकते हैं एक synchronized queue या और भी बेहतर नया ConcurrentQueue<T> (आप .NET 3.5 या उससे अधिक कोड किया है)!

+0

धन्यवाद, इवेंट लॉग कैसे उत्पन्न करें .... –

1

एकाधिक उत्पादकों, एकल उपभोक्ता बहु लड़ी कतार संचार के लिए सबसे आसान परिदृश्य है। एक थ्रेड-कतार को कंडीशन वेरिएबल/म्यूटेक्स और एक std :: queue के संयोजन के रूप में कार्यान्वित किया जा सकता है (यदि आप कतार पूर्ण करना चाहते हैं तो एक सीवी जोड़ें)।

उपभोक्ता सीवी पर इंतजार कर रहा है, जबकि कतार खाली है। कतार में जोड़ने के दौरान उत्पादक सिग्नल (भेजना)।

1

आप जो योजना बना रहे हैं वह क्लासिक निर्माता उपभोक्ता कतार है जो कुछ काम करने के लिए कतार पर वस्तुओं का उपभोग करने वाले थ्रेड के साथ है। इसे एक "अभिनेता" या "सक्रिय वस्तु" नामक उच्च स्तर के निर्माण में लपेटा जा सकता है।

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

http://www.drdobbs.com/go-parallel/article/showArticle.jhtml;jsessionid=UTEXJOTLP0YDNQE1GHPSKH4ATMY32JVN?articleID=225700095

संबंधित मुद्दे