2011-03-06 17 views
7

नींद समारोह की मेरी समझ यह है कि यह "कम से कम अर्थशास्त्र" यानी नींद (5) की गारंटी देता है कि थ्रेड 5 सेकंड तक सो जाता है, लेकिन यह 5 सेकंड से अधिक समय तक अवरुद्ध हो सकता है अन्य कारक। क्या वास्तव में निर्दिष्ट समय अवधि के लिए सोने का कोई तरीका है (व्यस्त प्रतीक्षा किए बिना)।एक सटीक अवधि के लिए सोना

+4

http://en.wikipedia.org/wiki/Real-time_operating_system –

+2

"व्यस्त प्रतीक्षा किए बिना" <- आप व्यस्त प्रतीक्षा के साथ भी ऐसा नहीं कर सकते हैं। प्रतीक्षा करते समय आपका धागा बाधित हो सकता है। (शायद कुछ वास्तविक समय विंडोज प्राथमिकता उपयोगी हो सकती है) –

+4

"सटीक" परिभाषित करें। यहां तक ​​कि एक हार्डवेयर बाधा से जुड़े हाथ कोडित असेंबलर के साथ भी आपको कैश मिस के कारण प्रभाव पड़ने होंगे और यहां तक ​​कि निर्देश पाइपलाइन को साफ़ करने और फिर से भरने की प्रतीक्षा भी होगी। व्यस्त लूपिंग के साथ भी आप microseconds द्वारा बंद होने जा रहे हैं। "सटीक" क्या है? –

उत्तर

14

जैसा कि अन्य ने कहा है, आपको वास्तव में एक वास्तविक समय ओएस का उपयोग करने और इसे प्राप्त करने के लिए उपयोग करने की आवश्यकता है। सटीक सॉफ्टवेयर समय काफी मुश्किल है।

हालांकि ... हालांकि सही नहीं है, आपको प्रक्रिया की प्राथमिकता को बढ़ावा देने के लिए "सामान्य" से बहुत बेहतर परिणाम मिल सकते हैं, जिसके लिए बेहतर समय की आवश्यकता होती है। विंडोज़ में आप इसे SetPriorityClass फ़ंक्शन के साथ प्राप्त कर सकते हैं।यदि आप प्राथमिकता को उच्चतम स्तर (REALTIME_PRIORITY_CLASS: 0x00000100) पर सेट करते हैं तो आपको अधिक बेहतर समय के परिणाम मिलेंगे। दोबारा - यह सही नहीं होगा जैसा कि आप पूछ रहे हैं।

यह विंडोज़ की तुलना में अन्य प्लेटफॉर्म पर भी संभव है, लेकिन मेरे पास ऐसा करने का कोई कारण नहीं है इसलिए इसका परीक्षण नहीं किया गया है।

संपादित करें: एंडी टी द्वारा टिप्पणी के अनुसार, यदि आपका ऐप बहु-थ्रेडेड है तो आपको थ्रेड को आवंटित प्राथमिकता के लिए भी देखना होगा। विंडोज के लिए यह here दस्तावेज है।


कुछ पृष्ठभूमि ...

कुछ समय पहले मैं SetPriorityClass इस्तेमाल किया एक आवेदन जहाँ मैं वास्तविक समय उच्च गति वीडियो का विश्लेषण कर रहा था पर प्राथमिकता बढ़ावा देने के लिए और मैं एक फ्रेम को याद नहीं कर सके। फ्रेम्स पर नियमित (बाहरी फ्रेमग्राबर एचडब्ल्यू द्वारा संचालित) 300 फ्रेम प्रति सेकेंड (एफपीएस) की आवृत्ति पर पीसी पर पहुंच रहे थे, जिसने मैंने प्रत्येक फ्रेम पर एक एचडब्लू इंटरप्ट को निकाल दिया था। चूंकि समय बहुत महत्वपूर्ण था, इसलिए मैंने अंतराल के समय (QueryPerformanceCounter सामान का उपयोग करके) पर बहुत सारे आंकड़े एकत्र किए, यह देखने के लिए कि वास्तव में स्थिति कितनी खराब थी, और परिणामी वितरण पर चिंतित था। मेरे पास आँकड़े आसान नहीं हैं, लेकिन मूल रूप से विंडोज सामान्य प्राथमिकता पर चलने पर इस तरह महसूस होने पर बाधा की सेवा कर रहा था। हिस्टोग्राम बहुत गन्दा थे, क्योंकि stdev मेरी ~ 3ms अवधि से अधिक व्यापक है। अक्सर मुझे इंटरप्ट सर्विसिंग में 200 मीटर या इससे अधिक की विशाल अंतराल होती है (याद रखें कि बाधा लगभग हर 3 एमएस निकाल दी जाती है) !! यानी: एचडब्ल्यू इंटरप्ट्स सटीक से एफएआर हैं! ओएस आप के लिए क्या करने का फैसला करता है उसके साथ अटक गए हैं।

हालांकि - जब मैंने REALTIME_PRIORITY_CLASS उस प्राथमिकता के साथ सेटिंग और बेंचमार्क की खोज की, तो यह महत्वपूर्ण बेहतर था और सेवा अंतराल वितरण अत्यंत तंग था। मैं 300 एफपीएस के 10 मिनट चला सकता हूं और एक फ्रेम को याद नहीं कर सकता। मापित इंटरप्ट सर्विसिंग अवधि एक कड़े वितरण के साथ बिल्कुल 1/300 एस थी।

इसके अलावा - ओएस में अन्य चीजों को बेहतर बनाने में मदद करने के लिए ओएस क्या कर रहा है, जो ऐप में बेहतर काम कर रहा है, जहां यह महत्वपूर्ण है। उदाहरण: अन्य पृष्ठभूमि के साथ सटीक समय प्राप्त करने की कोशिश करते समय कोई पृष्ठभूमि वीडियो ट्रांसकोडिंग या डिस्क डी-ड्रैगिंग या कुछ भी नहीं !!

सारांश में:

  1. आप वास्तव में इस की जरूरत है, एक वास्तविक समय ओएस
  2. के साथ जाने आप एक वास्तविक समय ओएस (असंभव या अव्यावहारिक) का उपयोग नहीं कर सकते हैं अपनी प्रक्रिया प्राथमिकता बढ़ाने होगा संभवतया आपके समय में काफी सुधार हुआ है, क्योंकि यह मेरे लिए किया गया है
  3. एचडब्ल्यू इंटरप्ट्स ऐसा नहीं करेंगे ... ओएस को अभी भी उनकी सेवा करने का निर्णय लेना होगा!
  4. सुनिश्चित करें कि आपके पास ओएस ध्यान
  5. के लिए प्रतिस्पर्धा करने वाली कई अन्य प्रक्रियाएं नहीं हैं, यदि समय आपके लिए वास्तव में महत्वपूर्ण है, तो कुछ परीक्षण करें। हालांकि चलाने के लिए कोड प्राप्त करना ठीक है जब आप इसे बहुत आसान नहीं करना चाहते हैं, तो इस विचलन को मापना काफी आसान है। पीसी में उच्च प्रदर्शन काउंटर (जो आप QueryPerformanceCounter के साथ प्राप्त करते हैं) बेहद अच्छे हैं।

चूंकि यह सहायक हो सकता है (हालांकि थोड़ा सा विषय), यहां एक छोटी सी कक्षा है जिसे मैंने विंडोज मशीन पर उच्च प्रदर्शन काउंटर का उपयोग करने के लिए बहुत समय पहले लिखा था।यह अपने परीक्षण के लिए उपयोगी हो सकता है:

CHiResTimer.h

#pragma once 
#include "stdafx.h" 
#include <windows.h> 

class CHiResTimer 
{ 
private: 
    LARGE_INTEGER frequency; 
    LARGE_INTEGER startCounts; 
    double ConvertCountsToSeconds(LONGLONG Counts); 
public: 
    CHiResTimer(); // constructor 
    void ResetTimer(void); 
    double GetElapsedTime_s(void); 
}; 

CHiResTimer.cpp

#include "stdafx.h" 
#include "CHiResTimer.h" 

double CHiResTimer::ConvertCountsToSeconds(LONGLONG Counts) 
{ 
    return ((double)Counts/(double)frequency.QuadPart) ; 
} 

CHiResTimer::CHiResTimer() 
{ 
    QueryPerformanceFrequency(&frequency); 
    QueryPerformanceCounter(&startCounts); // starts the timer right away 
} 

void CHiResTimer::ResetTimer() 
{ 
    QueryPerformanceCounter(&startCounts); // reset the reference counter 
} 

double CHiResTimer::GetElapsedTime_s() 
{ 
    LARGE_INTEGER countsNow; 
    QueryPerformanceCounter(&countsNow); 
    return ConvertCountsToSeconds(countsNow.QuadPart - startCounts.QuadPart); 
} 
+2

बहुत बढ़िया कहानी और कोड प्रदान किए गए बहुत सारे :) दयालुता मुझे केवल +1 देने के लिए मिला है। – sarnold

+0

और यदि प्रोग्राम बहुप्रचारित है, तो आपको सोने के थ्रेड के लिए भी उच्च प्राथमिकता निर्दिष्ट करने की आवश्यकता है –

+0

@AndyT - अच्छा बिंदु, मैं अपडेट करूंगा। धन्यवाद! – Russ

0

नहीं। क्योंकि आप हमेशा सही समय पर थ्रेड को संभालने के लिए ओएस पर निर्भर रहते हैं।

2

ठीक है, यदि आप एक कठिन समस्या से निपटने के लिए प्रयास करें, और सटीक समय को प्राप्त करने संभव नहीं है: सबसे अच्छा आप कर सकते हैं hardware interrupts उपयोग करने के लिए है, और कार्यान्वयन दोनों अपने अंतर्निहित हार्डवेयर पर निर्भर करेगा, और आपके ऑपरेटिंग प्रणाली (अर्थात्, आपको a real-time operating system की आवश्यकता होगी, जो कि सबसे नियमित डेस्कटॉप ओएस नहीं हैं)। आपका सटीक लक्ष्य मंच क्या है?

5

सं

कारण यह "कम से कम अर्थ विज्ञान में" है, क्योंकि है कि जो 5 सेकंड के बाद कुछ अन्य धागा व्यस्त हो सकता है।

प्रत्येक धागे को ऑपरेटिंग सिस्टम से समय का टुकड़ा मिलता है। ऑपरेटिंग सिस्टम उस क्रम को नियंत्रित करता है जिसमें थ्रेड चलाए जाते हैं।

जब आप सोने के लिए धागा डालते हैं, तो ओएस थ्रेड को प्रतीक्षा सूची में रखता है, और जब टाइमर ऑपरेटिंग सिस्टम "थ्रेड" पर होता है।
इसका मतलब है कि थ्रेड को सक्रिय थ्रेड सूची में वापस जोड़ा गया है, लेकिन यह गारंटी नहीं है कि टी को पहले स्थान पर जोड़ा जाएगा। (क्या होगा यदि उस विशिष्ट सेकेंड में 100 धागे जागने की ज़रूरत है? पहले कौन जाएगा?)

2

जैसा कि पिछले उत्तरदाताओं ने कहा था: सटीक होने का कोई तरीका नहीं है (कुछ सुझाए गए रीयलटाइम-ओएस या हार्डवेयर इंटरप्ट्स और यहां तक ​​कि वे नहीं हैं सटीक)। मुझे लगता है कि आप जो खोज रहे हैं वह कुछ ऐसा है जो नींद() फ़ंक्शन से अधिक सटीक है और आप पाते हैं कि आपके ओएस के आधार पर उदा। विंडोज स्लीप() फ़ंक्शन या जीएनयू के तहत नैनोस्लीप() फ़ंक्शन।

http://msdn.microsoft.com/en-us/library/ms686298%28VS.85%29.aspx

http://www.delorie.com/gnu/docs/glibc/libc_445.html

दोनों में कुछ मिलीसेकेंड के भीतर आप परिशुद्धता दे देंगे।

+0

+1 - यहां तक ​​कि आरटीओएस भी इसे प्राप्त करने में सक्षम नहीं हैं। – mouviciel

0

मानक सी का उपयोग करके निर्दिष्ट समय अवधि के लिए सोने का कोई तरीका नहीं है। आपको कम से कम एक तृतीय पक्ष लाइब्रेरी की आवश्यकता होगी जो अधिक ग्रैन्युलरिटी प्रदान करेगी, और आपको एक विशेष ऑपरेटिंग सिस्टम कर्नेल जैसे वास्तविक- समय लिनक्स कर्नेल।

उदाहरण के लिए, यहां एक discussion of how close you can come on Win32 systems है।

यह एक सी सवाल नहीं है।

4

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

या SCHED_RR का उपयोग करके आप sched_setscheduler(2) कॉल के साथ रीयलटाइम कार्य के रूप में अपनी प्रक्रिया को शेड्यूल कर सकते हैं। दोनों में अर्थशास्त्र में मामूली अंतर है, लेकिन यह जानना पर्याप्त हो सकता है कि SCHED_RR कार्य अंततः प्रक्रिया स्लाइडर को समय स्लाइस के कारण प्राथमिकता के किसी अन्य कार्य को छोड़ देगा, जबकि SCHED_FIFO कार्य केवल सीपीयू को दूसरे कार्य में छोड़ देगा ब्लॉकिंग I/O या sched_yield(2) पर एक स्पष्ट कॉल के कारण समान प्राथमिकता।

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

लिनक्स के वेरिएंट उपलब्ध हैं जो हार्ड-रीयलटाइम गारंटी प्रदान करने के लिए काम कर रहे हैं। RTLinux में commercial support है; Xenomai और RTAI लिनक्स के लिए रीयलटाइम एक्सटेंशन के प्रतिस्पर्धी कार्यान्वयन हैं, लेकिन मुझे उनके बारे में और कुछ नहीं पता है।

+0

+1 – fayyazkl

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