2011-03-16 16 views
6

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

आईपीसी के माध्यम से डेटा प्रकाशित करने के अनुरोध को प्राप्त करने के लिए, कार्यक्रम को IPC_listenwait (wait_time) कॉल करना होगा; फिर यदि प्रकाशित करने का अनुरोध प्राप्त होता है, तो "सुननेवाले" एक हैंडलर को नवीनतम डेटा प्रकाशित करने के लिए बुलाया जाता है।

एक विकल्प एक धागे की तरह में यह करने के लिए है:

for(;;) { 
    read_serial(inputBuffer); 
    process_data(inputBuffer, processedData); //Process and store 
    IPC_listenwait(wait_time); //If a request to publish is received during this, 
}       //then a handler will be invoked and the newest piece of   
          //processedData will be published to other modules 

publishRequestHandler() { //Invoked when a message is received during IPC_listenwait 
    IPC_publish(newest(processedData)); 
} 

और यह काम करता है, लेकिन आवेदन के लिए यह महत्वपूर्ण है कि कार्यक्रम नए डेटा प्रकाशित करने के लिए अनुरोध करने के लिए बहुत संवेदनशील है, और कहा कि प्रकाशित डेटा नवीनतम उपलब्ध है। ये लक्ष्य उपरोक्त से संतुष्ट नहीं हैं क्योंकि प्रक्रिया सुनने के बाद डेटा पहुंच सकता है और संदेश प्रकाशित करने के अनुरोध से पहले प्राप्त किया जाता है। या जब संदेश प्रकाशित करने का अनुरोध आने वाला है, तो प्रक्रिया पढ़ने/प्रसंस्करण हो सकती है, लेकिन अगली आईपीसी_लिस्टनवाइट कॉल तक इसे सेवा करने में सक्षम नहीं होगी।

readThread() { 
    for(;;) { //pseudocode 
     select(); 
     read(inputBuffer); 
     process(inputBuffer, processedData); 
    } 
} 

और बस भेजे गए संदेशों के लिए सुन मुख्य थ्रेड है:

mainThread() { 
    IPC_listenwait(forever); 
} 

publishRequestHandler() { //Invoked when a message is received during IPC_listenwait 
    IPC_publish(newest(processedData)); 
} 

केवल डिजाइन मैं के बारे में सोच सकते हैं एक धागा पढ़ने के लिए है, जो की तरह ही कुछ करना होगा करने के लिए है

क्या यह डिज़ाइन आप उपयोग करेंगे? यदि हां, तो क्या मुझे संसाधित डेटा लिखने या लिखने पर एक सेमफोर का उपयोग करने की आवश्यकता होगी?

क्या इससे मुझे अच्छी प्रतिक्रिया मिलेगी?

धन्यवाद

उत्तर

4

आप अधिकतर सही रास्ते पर हैं।

एक चीज जो आपको देखना है, वह प्रकाशित करने योग्य डेटा तक समवर्ती पहुंच है, क्योंकि आप नहीं चाहते हैं कि एक थ्रेड इसे क्लोबबर कर रहा हो, जबकि कोई इसे पढ़ने की कोशिश कर रहा है। इसे रोकने के लिए, किसी भी जोड़ी को बफर और म्यूटेक्स-संरक्षित पॉइंटर का उपयोग करें, जिसे किसी को भी वर्तमान माना जाता है। जब process_data() में कुछ तैयार है, तो इसे अपने परिणामों को गैर-वर्तमान बफर में डंप करना चाहिए, पॉइंटर म्यूटेक्स को लॉक करना चाहिए, पॉइंटर को नए डेटा वाले बफर में दोबारा डालें और फिर म्यूटेक्स को छोड़ दें। इसी प्रकार, प्रकाशक को वर्तमान डेटा को पढ़ने के दौरान पॉइंटर म्यूटेक्स को लॉक करना चाहिए, जो किसी भी चीज को मजबूर कर सकता है जो इसे प्रतीक्षा करने के लिए रोक सकता है। यह एकल, म्यूटेक्स-संरक्षित बफर होने से थोड़ा अधिक जटिल है लेकिन यह सुनिश्चित करेगा कि आपके पास हमेशा प्रकाशित होने के लिए कुछ नया चालू होगा जबकि नया डेटा तैयार किया जा रहा है।

यदि आपके प्रसंस्करण चरण में काफी समय लगता है कि आप पढ़ने के लिए डेटा के कई सेट प्राप्त कर सकते हैं, तो आप पढ़ने/प्रक्रिया धागे को दो में विभाजित कर सकते हैं और पाठक को यह सुनिश्चित करना चाहिए कि प्रोसेसर केवल नवीनतम और महानतम हो प्रसंस्करण सामग्री को समाप्त नहीं करेंगे जो आप कभी प्रकाशित नहीं करेंगे।

उत्कृष्ट पहला सवाल, वैसे भी। एक उत्थान है।

+0

आह, दो बफर समाधान सरल लेकिन प्रतिभा है! धन्यवाद –

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