2012-11-12 22 views
6

इस उदाहरण में https://stackoverflow.com/a/9980346/93647 और यहां Why is my disruptor example so slow? (प्रश्न के अंत में) 1 प्रकाशक है जो आइटम और 1 उपभोक्ता प्रकाशित करता है।1 प्रकाशक और 4 समांतर उपभोक्ताओं के साथ विघटनकर्ता उदाहरण

लेकिन मेरे मामले में उपभोक्ता कार्य अधिक जटिल है और कुछ समय लगता है। तो मैं 4 उपभोक्ताओं को चाहता हूं जो समानांतर डेटा को संसाधित करते हैं।

तो उदाहरण के लिए अगर निर्माता उपज संख्या: 1,2,3,4,5,6,7,8,9,10,11 ..

मैं consumer1 1,5,9 को पकड़ने के लिए चाहते हैं, ... उपभोक्ता 2 2,6,10 पकड़ने के लिए ... उपभोक्ता 3 को 3,7,11 पकड़ने के लिए ... उपभोक्ता 4 को 4,8,12 पकड़ने के लिए ... (ठीक है इन नंबरों को नहीं, विचार यह है कि डेटा समानांतर में संसाधित किया जाना चाहिए, मुझे परवाह नहीं है कि किस उपभोक्ता पर कुछ संख्या संसाधित की जाती है)

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

बेशक मैं केवल 4 रिंगबफर बना सकता हूं और 1 उपभोक्ता को 1 रिंग-बफर से जोड़ सकता हूं। इस तरह मैं मूल उदाहरण का उपयोग कर सकते हैं। लेकिन मुझे लगता है कि यह सही नहीं होगा। संभावना है कि 1 प्रकाशक (1 रिंगबफर) और 4 उपभोक्ताओं को बनाना सही होगा - जैसा कि मुझे चाहिए।

गूगल समूहों में एक बहुत ही simular प्रश्न के लिए लिंक जोड़ना: https://groups.google.com/forum/#!msg/lmax-disruptor/-CLapWuwWLU/GHEP4UkxrAEJ

तो हम दो विकल्प हैं: हर अलावा पर

  • एक अंगूठी कई उपभोक्ताओं (प्रत्येक उपभोक्ता होगा "वेक-अप", सभी उपभोक्ता के पास वही WaitStrategy होना चाहिए)
  • कई "एक अंगूठी - एक उपभोक्ता" (प्रत्येक उपभोक्ता केवल उस डेटा पर जाग जाएगा जो इसे संसाधित करना चाहिए। प्रत्येक उपभोक्ता के पास प्रतीक्षा प्रतीक्षा करनी चाहिए)।

उत्तर

1

EDIT: मैं उल्लेख करना भूल गया कि कोड आंशिक रूप से the FAQ से लिया गया है। मुझे नहीं पता कि यह दृष्टिकोण फ्रैंक के सुझाव से बेहतर या बदतर है।

परियोजना दस्तावेज के तहत गंभीर रूप से है, यह शर्म की बात है क्योंकि यह अच्छा लग रहा है।
वैसे भी निम्नलिखित स्निप (आपकी पहली कड़ी के आधार पर) की कोशिश - मोनो पर परीक्षण किया और ठीक हो रहा है:

using System; 
using System.Threading.Tasks; 
using Disruptor; 
using Disruptor.Dsl; 

namespace DisruptorTest 
{ 
    public sealed class ValueEntry 
    { 
     public long Value { get; set; } 
    } 

    public class MyHandler : IEventHandler<ValueEntry> 
    { 
     private static int _consumers = 0; 
     private readonly int _ordinal; 

     public MyHandler() 
     { 
      this._ordinal = _consumers++; 
     } 

     public void OnNext(ValueEntry data, long sequence, bool endOfBatch) 
     { 
      if ((sequence % _consumers) == _ordinal) 
       Console.WriteLine("Event handled: Value = {0}, event {1} processed by {2}", data.Value, sequence, _ordinal); 
      else 
       Console.WriteLine("Event {0} rejected by {1}", sequence, _ordinal);      
     } 
    } 

    class Program 
    { 
     private static readonly Random _random = new Random(); 
     private const int SIZE = 16; // Must be multiple of 2 
     private const int WORKERS = 4; 

     static void Main() 
     { 
      var disruptor = new Disruptor.Dsl.Disruptor<ValueEntry>(() => new ValueEntry(), SIZE, TaskScheduler.Default); 
      for (int i=0; i < WORKERS; i++) 
       disruptor.HandleEventsWith(new MyHandler()); 
      var ringBuffer = disruptor.Start(); 

      while (true) 
      { 
       long sequenceNo = ringBuffer.Next(); 
       ringBuffer[sequenceNo].Value = _random.Next();; 
       ringBuffer.Publish(sequenceNo); 
       Console.WriteLine("Published entry {0}, value {1}", sequenceNo, ringBuffer[sequenceNo].Value); 
       Console.ReadKey(); 
      } 
     } 
    } 
} 
+0

धन्यवाद! कोशिश करेंगे! – javapowered

+0

क्या आपको पता है कि रिंगबफर 'अगला() '' प्रकाशित करें 'विधियों को कॉल थ्रेड सुरक्षित है या नहीं? क्या मैं उन्हें समानांतर में बुला सकता हूं? क्या मैं दो अलग-अलग धागे रिंगबफर 'नेक्स्ट' विधि से कॉल कर सकता हूं? – javapowered

+0

भी यह कैसे आंतरिक रूप से विघटनकारी बनाता है? कितने धागे बनाए जाते हैं? क्या विघटनकर्ता प्रत्येक उपभोक्ता के लिए अलग धागा बनाता है? या कुछ प्रकार के थ्रेडपूल का उपयोग किया जाता है? – javapowered

0

रिंग-बफर के चश्मा से आप देखेंगे कि प्रत्येक उपभोक्ता आपके ValueEvent को संसाधित करने का प्रयास करेगा। आपके मामले में आपको इसकी आवश्यकता नहीं है।

मैं इसे इस तरह हल:

एक क्षेत्र अपने ValueEvent और जब एक उपभोक्ता घटना वह है कि मैदान पर परीक्षण लेता है, यदि वह पहले से संसाधित किया जाता है वह अगले क्षेत्र के लिए पर ले जाता है के लिए संसाधित जोड़ें।

सबसे सुंदर तरीका नहीं है, लेकिन यह बफर काम करता है।

+0

आपको लगता है कि मैदान पर तुल्यकालन की ज़रूरत है? क्या आप इसे 'अस्थिर' घोषित करते हैं या 'बूल' फ़ील्ड को अपडेट करने के लिए' इंटरलॉक 'कक्षा का उपयोग करते हैं? रिंगबफर के लिए एक से अधिक उपभोक्ता को कैसे संलग्न करें? मैं केवल एक उपभोक्ता को 'हैंडल एवेन्ट्सथथ' विधि में पास कर सकता हूं।अब तक मेरे लिए यह लगता है कि प्रत्येक रिंगबफर का उपयोग करके प्रत्येक रिंगबफर का उपयोग करके 4 रिंग-बफर और चक्र बनाना आसान होगा :) – javapowered

+0

यदि आप 4 रिंग बफर बनाते हैं, तो आप अंगूठी की "भार संतुलन" सुविधा खो देंगे बफर, और मुझे लगता है कि यही कारण है कि आप इसका उपयोग कर रहे हैं। आपके अन्य क्यू पर मैं जावा बफर का उपयोग कर रहा हूं इसलिए मैं आपको कोड नहीं दिखा सकता, लेकिन बस उदाहरणों का पालन करें, वे बहुत स्पष्ट हैं। इस विशेष मामले में – Frank

+0

मुझे "लोड संतुलन" की आवश्यकता नहीं है क्योंकि मेरे कार्य लगभग "बराबर" हैं और उन्हें 4 के बीच विभाजित करना ठीक है। हालांकि यह दिलचस्प विशेषता है। क्या मुझे जावा उदाहरणों का पालन करना चाहिए? क्योंकि मुझे लगभग कोई सी # उदाहरण नहीं मिल रहा है। – javapowered

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