2009-07-16 12 views
44

मैं पठार सीख रहा हूं और शर्तों की प्रतीक्षा कर रहा हूं। जहाँ तक मेरा बता सकते हैं एक ठेठ प्रतीक्षा धागा इस तरह है:पर्थ्रेड और प्रतीक्षा की शर्तें

pthread_mutex_lock(&m); 
while(!condition) 
    pthread_cond_wait(&cond, &m); 
// Thread stuff here 
pthread_mutex_unlock(&m); 

क्या मैं नहीं समझ सकता है क्यों लाइन while(!condition) आवश्यक है भले ही मैं pthread_cond_signal() का उपयोग धागा को जगाने के लिए।

मैं समझ सकता है कि मैं स्थिति का परीक्षण करने की जरूरत है अगर मैं pthread_cond_broadcast() का उपयोग करें, क्योंकि मैं जगा सभी इंतजार कर धागे और उनमें से एक म्युटेक्स अनलॉक (और इस प्रकार निष्पादन स्थानांतरित एक और ऊपर waked करने से पहले फिर से हालत झूठी कर सकते हैं थ्रेड जो उस बिंदु पर निष्पादित नहीं होना चाहिए)। लेकिन अगर मैं pthread_cond_signal() का उपयोग करता हूं तो मैं केवल एक थ्रेड उठता हूं इसलिए स्थिति सत्य होनी चाहिए। तो कोड इस तरह दिख सकता है:

pthread_mutex_lock(&m); 
pthread_cond_wait(&cond, &m); 
// Thread stuff here 
pthread_mutex_unlock(&m); 

मैंने ऐसा होने वाले नकली संकेतों के बारे में कुछ पढ़ा। क्या यह (और केवल यही) कारण है? मुझे नकली सिंगल क्यों होना चाहिए? या मुझे कुछ और नहीं मिला है?

मुझे लगता है संकेत कोड इस तरह है:

pthread_mutex_lock(&m); 
condition = true; 
pthread_cond_signal(&cond); // Should wake up *one* thread 
pthread_mutex_unlock(&m); 

उत्तर

43

वास्तविक कारण आपको थोड़ी देर में pthread_cond_wait डालना चाहिए, नकली wakeup की वजह से नहीं है। यहां तक ​​कि यदि आपकी हालत परिवर्तक में नकली wake नहीं है, तो आपको अभी भी एक सामान्य प्रकार की त्रुटि को पकड़ने के लिए लूप की आवश्यकता होगी। क्यूं कर? विचार करें कि तब हो सकता है एक से अधिक थ्रेड एक ही शर्त पर इंतजार:

Thread 1       Thread 2   Thread 3 
check condition (fails) 
(in cond_wait) unlock mutex 
(in cond_wait) wait 
           lock mutex 
           set condition 
           signal condvar 
           unlock mutex 
                lock mutex 
                check condition (succeeds) 
                do stuff 
                unset condition 
                unlock mutex 
(in cond_wait) wake up 
(in cond_wait) lock mutex 
<thread is awake, but condition 
is unset> 

समस्या यहाँ है कि धागा, इंतजार कर से पहले म्युटेक्स जारी करना चाहिए संभावित 'चोरी' जो कुछ भी थ्रेड के लिए प्रतीक्षा कर रहा था के लिए एक और धागा की इजाजत दी। जब तक यह गारंटी नहीं दी जाती है कि केवल एक थ्रेड उस स्थिति पर इंतजार कर सकता है, यह मानना ​​गलत है कि थ्रेड उठने पर स्थिति वैध होती है।

+1

बिल्कुल। ऊपर से मतदान किया। इसे स्वीकार किए गए उत्तर से अधिक ध्यान देना चाहिए। –

15

मान लीजिए आप स्थिति की जांच नहीं करते। तो आम तौर पर आप निम्नलिखित बुरी बात क्या हो रहा से बचने नहीं कर सकते हैं (कम से कम, आप इसे कोड की एक पंक्ति में टाल नहीं सकते):

Sender        Receiver 
locks mutex 
sets condition 
signals condvar, but nothing 
    is waiting so has no effect 
releases mutex 
            locks mutex 
            waits. Forever. 
बेशक

अपने दूसरे कोड उदाहरण इससे बचने के सकता है ऐसा करने से:

pthread_mutex_lock(&m); 
if (!condition) pthread_cond_wait(&cond, &m); 
// Thread stuff here 
pthread_mutex_unlock(&m); 

तो यह निश्चित रूप से मामला है कि अगर वहाँ सबसे एक रिसीवर पर ही कभी है, और अगर cond_signal केवल एक चीज थे कि यह जगा सकता है, तो यह केवल कभी जगा होगा जब शर्त सेट और इसलिए किया गया था होगा एक लूप की आवश्यकता नहीं होगी। नोस कवर क्यों दूसरा "अगर" सच नहीं है।

+0

मैं देखता हूं, इसलिए एक तर्क कारण (अंतहीन प्रतीक्षा) के कारण "अगर" की आवश्यकता होती है, लेकिन कार्यान्वयन के मुद्दों (नकली संकेत) के कारण वास्तव में कुछ समय की आवश्यकता होती है। – Emiliano

+0

हाँ जब मैंने पहली बार pthreads लाइब्रेरी का उपयोग किया तो मैंने एक ही प्रश्न पूछा। मैंने एक स्टेट वैरिएबल की जांच छोड़ दी और मेरा कार्यक्रम इंतजार से पहले संकेत करेगा। यह प्रतीक्षा/सिग्नल कार्यों का पूरा बिंदु है। स्मृति की स्थिति में कुछ म्यूटेक्स संरक्षित परिवर्तन पर प्रतीक्षा करने और सिग्नल करने के लिए। –

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