सी

2012-12-28 15 views
10

में तेज उत्पादक/धीमी उपभोक्ता मैंने सी में एक प्रोग्राम लिखा जो एक घटना की प्रतीक्षा करता है, और फिर system() फ़ंक्शन द्वारा बाहरी सिस्टम कमांड चलाता है।सी

while(true){ 
    wait_for_event(); 
    system("cmd"); 
} 

मैं इस पर एक seriuos समस्या है, cmd एक भारी आदेश है और कई सेकंड लेता है पूरा हो जाने की, मेरे ऐप इस समय सीमा में कुछ घटनाओं याद करते हैं।

तो मैं system समारोह है, जो बहुत भारी है, एक अन्य कार्यक्रम के लिए जाने का फैसला किया, तो मैं अपने कार्यक्रम बदल इस प्रकार है:

while(true){ 
    wait_for_event(); 
    write_to_fifo("cmd"); 
} 

और अन्य प्रोग्राम लिखा है:

while(true){ 
    system(read_from_pipe()); 
} 

लेकिन यह मदद नहीं करता है, क्योंकि यदि निर्माता (पहला कार्यक्रम) उपभोक्ता (द्वितीय कार्यक्रम) से तेज़ी से लिखता है, तो उपभोक्ता कुछ डेटा याद करता है!

क्या इस समस्या को संभालने का कोई तरीका है?

+4

घटनाओं को कैप्चर करने के लिए एक थ्रेड का उपयोग करें, उन्हें एक कतार में जोड़ें, और अपने उपभोक्ता उस कतार से खींचें। – Falmarri

+0

क्या उत्पादक सिंगल थ्रेडेड छोड़कर उपभोक्ता पर बोझ को कम करने के लिए कई धागे का उपयोग करना संभव है? यह माना जाता है कि यह एक हारने वाली लड़ाई है, लेकिन यह आपकी आवश्यकताओं को बचाने के लिए पर्याप्त हो सकती है। यदि आप अभी भी अतिरिक्त धागे के लिए बहुत अधिक हो जाते हैं तो आपको डेटा स्टोर भी देखना चाहिए। – pickypg

+0

आप अपनी पाइप कैसे सेट अप करते हैं?बेशक, अगर आप लगातार प्रक्रिया कर सकते हैं तो आप अधिक डेटा प्राप्त कर सकते हैं, कुछ "देने" जा रहा है। लेकिन बड़ी मात्रा में डेटा को धीरे-धीरे संसाधित करने के लिए पाइप का उपयोग करना पूरी तरह से संभव है। अन्यथा, यह 'cat myprog.c | gcc -o myprog' करने के लिए काम नहीं करेगा - और यह करता है - जीसीसी कई बार धीमा है, बिल्ली पाइप के जितनी तेजी से धक्का देगी। –

उत्तर

8

आप अपने मूल रूप — है कि करने के लिए कोड को वापस चाहिए, एक भी कार्यक्रम एक दूसरे कार्यक्रम — सिवाय इसके कि आप popen(3) कॉल के साथ system(3) कॉल की जगह बुला। अब कॉलिंग प्रोग्राम बाहरी कार्यक्रम से पढ़ने की लाइनों के साथ इवेंट चेकिंग के लिए कॉल को अंतःस्थापित कर सकता है।

यूनिक्स पाइप तंत्र यह सुनिश्चित करता है कि एक धीमी उपभोक्ता तेजी से निर्माता को प्रतीक्षा करेगी जब पाइप पूरा हो जाए।

तुम भी इतना है कि यह कभी नहीं बुला कार्यक्रम ब्लॉक कर सकते हैं, fileno(3) समारोह, ताकि बाहरी कार्यक्रम अतुल्यकालिक से पढ़ने बनाने के लिए select(2) या poll(2) के साथ संयुक्त पर गौर कर सकते हैं।

+0

आपके लिए त्वरित प्रतिक्रिया के लिए धन्यवाद। मैं लिनक्स के तहत सी प्रोग्रामिंग से परिचित नहीं हूं, क्या आप कृपया नमूना कोड दें। धन्यवाद – Maryam

+0

वाह! यह एक जादू की तरह काम करता है! धन्यवाद – Maryam

+0

आपको वास्तव में इस विषय पर पुस्तकों में से एक प्राप्त करना चाहिए। टुकड़े से टुकड़े टुकड़े करना इसके अंक हैं, लेकिन वहां एक गेस्टल्ट है जिसे आपको लेने की जरूरत है, और यह तब होता है जब आप इसे कम अवधि में सीखते हैं। मैं अनुशंसा करता हूं * यूनिक्स पर्यावरण * 2/ई डब्ल्यू रिचर्ड स्टीवंस द्वारा उन्नत प्रोग्रामिंग। ऐसी अन्य किताबें हैं। इस पुस्तक की उम्र से दूर मत बनो। यहां तक ​​कि पहला संस्करण अभी भी आधुनिक लिनक्स प्रोग्रामिंग के लिए 95% उपयोगी है। कर्नेल एपीआई और सी मानक लाइब्रेरी ने उस समय बहुत कुछ नहीं बदला है। –

2

यदि आपको केवल घटनाओं की संख्या की आवश्यकता है, तो आप वैश्विक काउंटर प्राप्त कर सकते हैं। दौड़ की स्थिति से बचने के लिए, आपको इसके बजाय एक सेमफोर का उपयोग करने की आवश्यकता हो सकती है। बेशक आपको दो धागे की आवश्यकता होगी।

चूंकि आपकी घटनाओं में महत्वपूर्ण है, आने वाली डेटा को स्टोर करने के लिए एक सूची (या पर्याप्त संख्या में स्लॉट के साथ सरणी) का उपयोग किया जा सकता है। आप इस सूची की सुरक्षा के लिए एक म्यूटेक्स का उपयोग कर सकते हैं।

+0

नहीं, घटनाओं में कुछ महत्वपूर्ण डेटा है और उन्हें संसाधित और अन्य जगहों पर संग्रहीत किया जाना चाहिए। – Maryam

2

आप स्पष्ट रूप से अपने बाहरी कार्यक्रम शुरू कर सकता है, fork(2), execve(2), waitpid(2) और शायद pipe(2), dup2(2) और अन्य syscalls का उपयोग कर।

आपको शायद एक ईवेंट लूप की आवश्यकता है। आप poll(2) syscall (या शायद libev जैसे ईवेंट लूप लाइब्रेरी का उपयोग कर सकते हैं, जो poll का उपयोग करता है) का उपयोग कर सकता है।

मैं कोडिंग से पहले एक अच्छा advanced linux programming book पढ़ने के लिए घंटों का समय लेने का सुझाव देता हूं।