2009-08-03 23 views
18
#include <stdio.h> 

int main() { 
    while(!DONE) { 
    /* check for stuff */ 
    } 
    return 0; 
} 

उपरोक्त कोड नमूना 100% सीपीयू का उपयोग करता है जब तक कि सही नहीं हो जाता है। मैं ऐसे प्रोग्राम को कैसे कार्यान्वित कर सकता हूं जो लूप करता है और केवल समाप्त होने पर ही समाप्त हो जाता है, लेकिन जो 100% सीपीयू का उपयोग नहीं करता है? आधुनिक भाषाएं ऐप.प्रोसेस मैसेज या कुछ ऐसा कुछ उपयोग करती हैं जो ओएस को इस पल के लिए नियंत्रण देती है और फिर लूप पर वापस आती है।सी मुख्य लूप 100% सीपीयू

मैं सेल्सियस पर नया हूँ, जाहिर है ... नवीनतम जीसीसी, लिनक्स और विंडोज का उपयोग कर

नींद (पूर्णांक मिलीसेकंड)

+8

आप एक तुल्यकालन वस्तु, एक है कि आप जब तक यह संकेत हो जाता है पर इंतजार कर सकते हैं, इस तरह आप सब पर सीपीयू का उपभोग नहीं होगा का उपयोग करना चाहिए। –

+2

'क्या किया गया' और यह शून्य होने का कारण क्या होगा? संभवतः जब तक 'सामान की जांच' तक प्रोसेसिंग जारी रखने के लिए यह समझ में आता है कि गैर-शून्य होने के लिए सेट किया गया कुछ ऐसा मूल्यांकन करता है? –

+0

लास वी। कार्ल्सन: आपका समाधान समझ में आता है (शायद यह बहुत समझ में आता है, लेकिन मेरे पास यह ज्ञान नहीं है)। क्या आप विस्तार से बता सकते हैं? क्या मुझे धागे की जांच करनी चाहिए? (एक उदाहरण अच्छा होगा) चार्ल्स बेली: डोन होना चाहिए (डीओएन के बजाए किया गया) और यह 1 पर सेट किया जाएगा जब उपयोगकर्ता ऐप छोड़ने का विकल्प चुनता है, उदाहरण के लिए। मुझे खेद है कि अगर मैं खुद को पर्याप्त रूप से समझा नहीं सकता .. – pwseo

उत्तर

16

यह निर्भर करता है कि आप इस लूप के अंदर क्या करना चाहते हैं।

यदि आप लूप के अंदर इंतजार कर रहे हैं (यानी यदि कुंजीपटल {कुछ करें} तो आपका तंत्र सिस्टम संसाधनों को बर्बाद कर देगा, बदले में कुछ भी नहीं दे रहा है। एक तेज प्रोसेसर बस अधिक निष्क्रिय लूप बना देगा। इसे घटनाओं की प्रतीक्षा करके हल किया जा सकता है। बस सो जाओ, लेकिन अधिमानतः एक घटना जो ट्रिगर करता है कि कुछ अर्थपूर्ण किया जा सकता है। उदाहरण के लिए, एक फ़ाइल ऑपरेशन (stdin भी एक फ़ाइल है) एक पोर्टेबल तंत्र होगा। यह डेटा उपलब्ध होने तक अन्य अनुप्रयोगों के लिए रास्ता देगा। जब आप बन जाते हैं अधिक विशिष्ट इसे सेमफोर या संकेतों में गोता लगाने की आवश्यकता हो सकती है जो अक्सर ओएस पर निर्भर होते हैं। एक अमूर्त परत इसे हल कर सकती है।

यदि आप कुछ उपयोगी कर रहे हैं (यानी बहुत सारे डेटा को प्रोसेस करना), तो 100% सीपीयू लोड इसका मतलब है कि प्रोसेसर हम हैं सबसे कुशल तरीके से एड। आप अन्य और संभवतः उच्च प्राथमिकता वाले कार्यों को देने के लिए ऑपरेटिंग सिस्टम पर भरोसा कर सकते हैं।

नींद जैसे फ़ंक्शन का उपयोग करने से सीपीयू उपयोग कम हो जाएगा, लेकिन आपका आवेदन धीमा हो जाएगा। स्वीकार्य प्रदर्शन और सीपीयू लोड के बीच इसे ट्रेडऑफ प्राप्त करने की आवश्यकता होगी। अधिकतम निष्पादन गति आपके नींद पैरामीटर द्वारा परिभाषित की जाएगी, और अब सीपीयू गति से नहीं। इसके अलावा, अगर बिजली एक चिंता है (यानी बैटरी जीवनकाल), तो इसके लिए सीपीयू को जागने की आवश्यकता होगी (नींद की अवधि समाप्त) बिना काम करने के; यानी सिस्टम संसाधनों का एक अलग अपशिष्ट।

+0

मुझे लगता है कि मुझे सेमफोर और सिग्नल सीखना होगा उस पर कोई विशिष्ट पॉइंटर्स? :) – pwseo

+2

मुख्य पाश के अंदर किस तरह की प्रसंस्करण है? संदेश, संकेत, सेमफोर ऑपरेटिंग सिस्टम से संबंधित भाषा से संबंधित हैं। उदाहरण के लिए, http://www.ibm.com/developerworks/eserver/library/es-win32linux-sem.html दिखाता है कि विंडो बनाम लिनक्स में सेमेफोर कैसे प्रबंधित किए जाते हैं। यदि आपको दोनों का समर्थन करने की आवश्यकता है, तो आप या तो POSIX (जो कि विंडोज़ के लिए वैकल्पिक है, यानी साइगविन में) का उपयोग कर सकते हैं या कोड को प्लेटफ़ॉर्म-निर्भर मॉड्यूल में डाल सकते हैं जिसे आप प्रत्येक ओएस के लिए बनाते हैं। – Adriaan

1

उपयोग क्या आप वास्तव में जांच रहे हैं?

यदि आप कुछ अस्थिरता की जांच कर रहे हैं जो हार्डवेयर या किसी अन्य प्रक्रिया द्वारा बदला जाता है, तो बस अपने लूप में sleep पर कॉल करें।

यदि आप फ़ाइल डिस्क्रिप्टर या नेटवर्क सॉकेट डिस्क्रिप्टर पर इंतजार कर रहे हैं, तो आप अपने लूप में select या poll का उपयोग करना चाहेंगे ताकि वर्णनकर्ता के लिए खपत के लिए डेटा तैयार हो सके।

+3

नींद का तर्क वास्तव में कई सेकंड है, मिलीसेकंड नहीं। –

+1

मुझे लगता है कि यह वास्तव में ओएस पर निर्भर करता है ... जबकि आप यूनिक्स/लिनक्स/* बीएसडी के तहत पैरामीटर होने के पैरामीटर के बारे में सही हैं, मुझे लगता है कि मुझे याद है कि यह विंडोज के तहत मिलीसेकंड है ... हालांकि यह वर्षों से हो सकता है, इसलिए मैं कर सकता था गलत हो ... – Nicolas

+5

नींद() सेकंड की संख्या लेता है। usleep() (बीएसडी और POSIX) microseconds लेता है। नैनोस्लीप() (पॉज़िक्स भी) नैनोसेकंड लेता है। – qrdl

3

(एक पोर्टेबल समाधान बहुत अच्छा होगा!)

0

yield() का उपयोग करें।

+0

यह पोर्टेबल नहीं है, क्योंकि यह न तो सी मानक और न ही POSIX द्वारा परिभाषित किया गया है। –

+1

क्या यह अन्य प्रक्रियाओं को और अधिक समय नहीं देगा, फिर भी हर समय अन्य प्रक्रियाओं का उपभोग नहीं करते हैं? POSIX सिंक्रनाइज़ेशन के उपयोग के सुझाव के लिए – liori

0

यदि मैं सही ढंग से अनुमान लगा रहा हूं (मुझे इसके बारे में पता नहीं है), App.ProcessMessages के बराबर IO अवरुद्ध कर रहा है। और जैसा कि मुझे मल्टीटास्किंग ओएस पर सी के किसी भी कार्यान्वयन के बारे में पता नहीं है जो मतदान का उपयोग करता है, किसी भी मानक सी आईओ को सुरक्षित होना चाहिए।

5

आपके दो विकल्प मतदान होंगे, और किसी प्रकार की घटना अधिसूचना होगी।

मतदान कार्यक्रम के लिए सबसे आसान होगा - मूल रूप से आपके पास थ्रेड के माध्यम से थोड़ी देर के लिए आपकी धागा नींद आती है। यह अन्य कार्यों के लिए प्रोसेसर जारी करता है। नकारात्मकता यह है कि आपके "सामान की जांच" कोड में देरी होगी - इसलिए यदि आप एक सेकंड के लिए सो रहे हैं, तो आपके कोड की स्थिति का पता लगाने से पहले यह एक सेकंड तक हो सकता है। आपका कोड यहां बंदरगाह के लिए आसान होगा।

दूसरा विकल्प किसी POSIX सशर्त, या Windows ईवेंट या उस तरह कुछ पर प्रतीक्षा करना है। न केवल यह कोड बदला जाएगा, लेकिन फिर "जो सामान आप जांच रहे हैं" को ध्वज को ट्रिगर करने की आवश्यकता होगी ताकि यह कह सके कि यह किया गया है। यह थोड़ा कम पोर्टेबल कोड होगा, हालांकि प्लेटफार्म को दूर करने के लिए शायद पुस्तकालय हैं। लेकिन आपको घटना के तत्काल परिणाम मिलेंगे, और ऐसी चीजों के लिए कोई बर्बाद प्रोसेसर समय जांच नहीं होगा जो वहां नहीं हैं।

+1

+1। –

9

आपके पास कई विकल्प हैं:

  1. उपयोग नींद() समय-समय पर निरस्त करने और अन्य प्रक्रिया अनुमति देने के लिए मजबूर करने के लिए प्रक्रिया एक निम्न प्राथमिकता के स्तर पर सीपीयू
  2. भागो उपयोग करने के लिए - जो करने के लिए ओएस का कारण होगा कम CPU समय
  3. एक म्युटेक्स या अन्य तुल्यकालन वस्तु का प्रयोग करें पता लगाने के लिए जब काम उपलब्ध है निर्दिष्ट करें - जो उपभोक्ता किसी भी CPU समय से प्रक्रिया रखेंगे जब तक कि यह वास्तव में काम
  4. कर रहा है आप तेजी से आप इसे संसाधित कर सकते हैं काम मिलता है - आपको अभी भी आवश्यकता हो सकती है पूरी तरह से सीपीयू उपभोग करने से बचने के लिए किसी प्रकार की नींद/प्राथमिकता मॉडल से।

विकल्प # 2 प्लेटफॉर्म/ओएस तटस्थ तरीके से करना मुश्किल हो सकता है। आपकी सबसे अच्छी शर्त प्रक्रिया को लॉन्च करना और रनटाइम पर्यावरण में इसकी प्राथमिकता बदलना है।

0

विंडोज़ पर, आप windows.h पर परिभाषित नींद (int मिलीसेकंड) का उपयोग कर सकते हैं।

2

यदि मैं सही समझ गया, तो आपने टिप्पणियों में कहा कि अन्य धागे से बदला जा सकता है। यदि ऐसा है, तो स्थिति चर समझ में आता है। pthreads के साथ, एक करना होगा:

धागा कि इंतजार कर रहा है में:

pthread_mutex_lock(&mutex); 
while (!DONE) { 
    pthread_cond_wait(&cond, &mutex); 
} 
pthread_mutex_unlock(&mutex); 

अन्य धागे में, जब किया बदल गई है:

pthread_mutex_lock(&mutex); 
DONE = 1; 
pthread_cond_signal(&cond); 
pthread_mutex_unlock(&mutex); 
+0

आप किसी अन्य धागे से धागे को अनलॉक कर सकते हैं? – user457015

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