2011-06-10 18 views
10

मेरे पास एक लिनक्स सिस्टम पर चलने वाला थ्रेड है जिसे मुझे सटीक अंतराल के रूप में निष्पादित करने की आवश्यकता है। जैसे एक बार हर एमएस निष्पादित करें।लिनक्स, सटीक प्रोग्राम समय की आवश्यकता है। शेड्यूलर प्रोग्राम अप

वर्तमान में यह

timerfd_create(CLOCK_MONOTONIC, 0) 

साथ एक टाइमर बनाने, और फिर

timerfd_settime (fd, 0, &itval, NULL); 

एक अवरुद्ध कॉल पढ़ के साथ एक struct में वांछित सोने का समय गुजर द्वारा किया जाता है इस टाइमर जो रुकती है पर किया जाता है थ्रेड निष्पादन और रिपोर्ट्स वेकअप कॉल खो गया।

समस्या यह है कि उच्च आवृत्तियों पर, सिस्टम समय सीमा खोने लगता है, भले ही CPU उपयोग 10% से कम हो। मुझे लगता है कि यह शेड्यूलर के कारण है जो ब्लॉकिंग कॉल को जांचने के लिए अक्सर थ्रेड को जागता नहीं है। क्या कोई ऐसा आदेश है जिसका उपयोग मैं शेड्यूलर को निश्चित अंतराल पर धागे को जागने के लिए कह सकता हूं, जहां तक ​​यह संभव है? व्यस्त-प्रतीक्षा एक खराब विकल्प है क्योंकि सिस्टम कई अन्य कार्यों को संभालता है।

धन्यवाद।

+1

क्या आप इसे रीयल-टाइम शेड्यूलर पर चला रहे हैं? मेरे अनुभव में जो मिलीसेकंड के आदेश पर अंतराल के लिए पर्याप्त होना चाहिए, जब तक आपके कर्नेल में कोई बुरी तरह से व्यवहार करने वाले ड्राइवर न हों। (बेशक, लिनक्स एक विशेषज्ञ आरटीओएस नहीं है, और इस बात की कोई गारंटी नहीं है कि आप कभी भी समय सीमा याद नहीं करेंगे।) –

उत्तर

5

आपको आरटी लिनक्स * प्राप्त करने की आवश्यकता है, और उसके बाद नियमित अंतराल पर जागने की प्रक्रिया की आरटी प्राथमिकता बढ़ाएं।

अन्यथा, मुझे आपके कोड में समस्याएं नहीं दिखाई देती हैं, और यदि आपकी प्रक्रिया अवरुद्ध नहीं हो रही है, तो इसे ठीक काम करना चाहिए।

(*) आरटी लिनक्स - कुछ वास्तविक समय शेड्यूलिंग पैच के साथ एक ओएस लागू होता है।

+1

धन्यवाद वी जो, मैंने इस बारे में एक विकल्प के रूप में सोचा है। इस समय इस समय मैं एक सामान्य वेनिला संस्करण में बंद कर दिया गया हूं, लेकिन मैं इसे आगे देखूंगा। दूसरी तरफ, यदि मैं एक आरटी लिनक्स संस्करण चलाता हूं .. मुझे क्या गारंटी है कि शेड्यूलर ब्लॉकिंग कॉल की जांच के लिए सटीक अंतराल पर इस थ्रेड को जगाएगा? - एक और अधिक कुशल सुरक्षित तरीका होना चाहिए? –

+0

@K_scheduler इस बात पर निर्भर करता है कि आपको कितना अच्छा आरटी संस्करण मिलता है। आपके पास कठिन और मुलायम शेड्यूलिंग गारंटी है, और यह सब कार्यान्वयन पर निर्भर करता है। मुझे लगता है कि हार्ड गारंटी पर त्रुटि 1 एमएस (सुनिश्चित नहीं है) –

+3

उदाहरण के रूप में है, https://rt.wiki.kernel.org/index.php/CONFIG_PREEMPT_RT_ पैच – stefaanv

1

आप जो भी चाहते हैं वह करने में सक्षम नहीं होंगे जब तक कि आप इसे वास्तविक "वास्तविक समय ओएस" पर नहीं चलाते।

2

शेड्यूलर विलंबता को कम करने का एक तरीका है रीयलटाइम शेड्यूलर जैसे SCHED_FIFO का उपयोग करके अपनी प्रक्रिया को चलाने के लिए। sched_setscheduler देखें।

यह आम तौर पर विलंबता को बेहतर बनाने के लिए बहुत कम विलंबता में सुधार करेगा, लेकिन आपको लिनक्स के रीयलटाइम ब्रान्स, या रीयलटाइम ओएस जैसे वीएक्सवर्क्स, आरटीईएमएस या क्यूएनएक्स में स्थानांतरित करने की आवश्यकता होगी।

1

यदि यह x86 सिस्टम के लिए केवल लिनक्स है तो मैं एचपीईटी टाइमर का चयन करूंगा। मुझे लगता है कि सभी आधुनिक पीसी में इस हार्डवेयर टाइमर का निर्माण होता है और यह बहुत सटीक है। मैं आपको कॉलबैक को परिभाषित करने की अनुमति देता हूं जिसे प्रत्येक मिलीसेकंड कहा जाएगा और इस कॉलबैक में आप अपनी गणना कर सकते हैं (यदि वे सरल हैं) या कुछ सिंक्रनाइज़ेशन ऑब्जेक्ट (उदाहरण के लिए सशर्त चर) का उपयोग करके अन्य थ्रेड काम को ट्रिगर करें यहां कुछ उदाहरण दिया गया है इस टाइमर http://blog.fpmurphy.com/2009/07/linux-hpet-support.html

+0

धन्यवाद, लेकिन सिस्टम x86 विशिष्ट नहीं हो सकता है। –

0

शेड्यूलिंग क्लास को SCHED_FIFO पर सेट करने जैसी अन्य सलाह के साथ, आपको एक लिनक्स कर्नेल को उच्च पर्याप्त टिक दर के साथ संकलित करने की आवश्यकता होगी, जो आपकी समय सीमा को पूरा कर सकती है।

उदाहरण के लिए, 100 या 250 हर्ट्ज (प्रति सेकेंड टाइमर इंटरप्ट्स) के CONFIG_HZ के साथ संकलित कर्नेल उस समय से अधिक टाइमर ईवेंट को कभी भी प्रतिसाद नहीं दे सकता है।

आपको अपने टाइमर को वास्तव में थोड़ा सा होने की आवश्यकता है, जो आपको वास्तव में चाहिए, क्योंकि टाइमर को उनके अनुरोधित समय से आगे जाने की अनुमति है, लेकिन जल्दी ही समाप्त नहीं होने पर, इससे आपको बेहतर परिणाम मिलेंगे। यदि आपको 1 एमएस की आवश्यकता है, तो मैं इसके बजाय 999 के लिए पूछने की सिफारिश करता हूं।

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