2010-06-26 16 views
12

मैं iPhone ऑडियो बारे में एक अध्याय के माध्यम से काम कर रहा हूँ और कोड का एक वर्ग है कि मैं का मतलब नहीं कर सकते हैं भर में आ गए हैं:नींद() के बजाय चयन() का उपयोग क्यों करें?

while (aqc.playPtr < aqc.sampleLen) 
{ 
    select(NULL, NULL, NULL, NULL, 1.0); 
} 

(Full code sample is on pages 163-166)। कोड के बारे में मैं समझता हूं कि ऑडियो को किसी अन्य थ्रेड पर संसाधित किया जा रहा है और जबकि लूप केवल मुख्य थ्रेड को समाप्त होने से रोकने के लिए है, जबकि ऑडियो अभी भी संसाधित हो रहा है।

मुझे समझ में नहीं आता है कि select()sleep() के बजाय क्यों उपयोग किया जा रहा है।

जो मैंने पढ़ा है उससे select() का उपयोग I/O में परिवर्तनों की निगरानी करने के लिए किया जाता है और इसे पास करने से NULLs कुछ सार्थक नहीं करता है। मैंने sleep() का उपयोग कर कोड चलाया है और यह अपेक्षा के अनुसार काम करता है।

+0

डरावना। मुझे नहीं पता था कि लोग अभी भी उस पुरानी चाल का उपयोग करते हैं। और यह एक प्रतीत होता है कि एक नया और चमकदार वास्तुकला जहां 'नींद' के अन्य साधनों का अर्थ उपलब्ध होना चाहिए। इस तरह के कोड के प्रोग्रामर/लिखने पर शर्म की बात है। –

+5

@JensGustedt एक पैरामीटर के रूप में 'डबल' को पार करने के रूप में डरावना नहीं है जब फ़ंक्शन ** सूचक ** को 'स्ट्रक्चर टाइमवल' – JeremyP

+0

@JensGustedt से अपेक्षा करता है यह वास्तव में सोने का एक बहुत ही सुरक्षित तरीका है, क्योंकि नींद() शायद नहीं काम उदाहरण सिग्नल हैंडलर में। – LubosD

उत्तर

17

सटीक उप दूसरे प्रतीक्षा के लिए अनुमति का चयन करें, और नींद से अधिक पोर्टेबल है। प्रतीक्षा करने के अन्य तरीके हैं, this question देखें।

लेकिन चयन का टाइमआउट पैरामीटर एक फ्लोट नहीं होना चाहिए बल्कि संरचना समय के लिए एक सूचक होना चाहिए। मैं आश्चर्यचकित हूं कि आपके द्वारा संकलित किए गए कोड को भी संकलित किया गया है। अधिक: इस अजीब सशर्त चयन के बाद बिना शर्त नींद (1) होती है। मुझे व्यर्थ लग रहा है।

9

NULLrfds, wfds और efds साथ select() का उपयोग करना है portably subsecond संकल्प के साथ सो रही है की एक मुहावरेदार रास्ता (निम्न स्तर POSIX का मेरा ज्ञान लगभग गैर existant है।)।

+1

लेकिन 'टाइमआउट' (5 वां तर्क) नहीं है (संभवतः पूर्ण) पॉइंटर को 'स्ट्रक्चर टाइमवल' के लिए माना जाता है? –

+0

@ मैथ्यू हां, सही। – ninjalj

+0

@MatthewFlaschen और उस मामले में यह हमेशा के लिए सो जाएगा। –

-1

ऐसा करने का कोई कारण नहीं है। स्लीप() या तो कभी भी कोई कारण नहीं है। किसी को कम से कम एक घटना की उम्मीद करनी चाहिए - प्रोग्राम शट डाउन अनुरोध।

+0

मुझे नहीं पता कि उसे किसी चीज़ के साथ क्या करना है। शट डाउन अनुरोध से 'सिगरेटर' का कारण बनता है जिसे सिग्नल हैंडलर, डिफ़ॉल्ट या अन्यथा द्वारा नियंत्रित किया जाता है। –

+2

कि न तो सवाल का जवाब देता है, न ही बहुत समझ में आता है ... सोने के लिए बहुत अच्छे कारण हैं, खासकर एम्बेडेड प्लेटफॉर्म पर (जिसमें आईफोन शामिल है, मुझे लगता है) –

+0

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

4

अच्छा, नींद (3) संकेतों का उपयोग करके लागू किया जा सकता है। यह मंच पर निर्भर करता है।

जब आप चयन (2) और मतदान (2) का उपयोग करते हैं, तो आप जानते हैं कि कोई सिग्नल शामिल नहीं होगा, जो अक्सर बहुत उपयोगी होता है। उदाहरण के लिए, यदि आप अलार्म (2) का उपयोग कर रहे हैं, तो आपको नींद (3) का भी उपयोग नहीं करना चाहिए, क्योंकि "अलार्म और नींद में कॉल मिश्रण करना एक बुरा विचार है" (मैन पेज के अनुसार।)

इसके अलावा, चुनने और मतदान आपको सोने के दौरान मिलीसेकंद ग्रैन्युलरिटी देते हैं, लेकिन सोने के दौरान सेकंड के मामले में केवल ग्रैन्युलरिटी होती है।

3

आप अपने आवेदन में SIGALM संकेत का उपयोग करें और आप (u)sleep कार्यों का उपयोग, जब SIGALRM होता कार्यक्रम तुरंत नींद समारोह से लौटने के लिए, तो सोने के लिए सबसे अच्छा तरीका है select समारोह पर प्रतीक्षा करने के लिए है जब।

struct timeval tv; 

tv.tv_sec = 1; 
tv.tv_usec = 1000; 

do 
{ 
    ret = select(1, NULL, NULL, NULL, &tv); 
} 
while((ret == -1)&&(errno == EINTR)); //select is interruped too 
+0

समय बीतने के लिए 'टीवी' समायोजित करें का चयन करें? यदि नहीं, तो आपका प्रतीक्षा लूप प्रत्येक 'EINTR' अवसर पर पूरे समय अंतराल को पुनरारंभ करेगा। –

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