pthreads
सशर्त चर
खोज…
परिचय
सशर्त चर उन मामलों में उपयोगी होते हैं जहां आप एक थ्रेड चाहते हैं जो किसी अन्य थ्रेड में होने वाली चीज़ की प्रतीक्षा करें। उदाहरण के लिए, एक उत्पादक या उपभोक्ता परिदृश्य में एक या एक से अधिक उत्पादक धागे और एक उपभोग करने वाले धागे के साथ, सशर्त चर का उपयोग उस खपत धागे को इंगित करने के लिए किया जा सकता है जो नया डेटा उपलब्ध है।
टिप्पणियों
सामान्य प्रक्रिया
एक सशर्त चर पर इंतजार (निर्माता / उपभोक्ता उदाहरण में कतार) हमेशा एक म्यूटेक्स (निर्माता / उपभोक्ता उदाहरण में कतार कतार) के लिए युग्मित होता है, और हमेशा एक "सामान्य" राज्य चर के लिए भी युग्मित होना चाहिए (कतार) ) निर्माता / उपभोक्ता उदाहरण में)। जब सही तरीके से उपयोग किया जाता है, तो यह सुनिश्चित करता है कि उपभोक्ता में कोई नया डेटा याद न हो।
सामान्य तौर पर, प्रक्रिया होनी चाहिए:
- सिग्नलिंग थ्रेड के लिए:
- म्यूटेक्स को लॉक करें
- किसी भी डेटा और राज्य चर को अपडेट करें
- संकेत स्थिति चर
- म्यूटेक्स को अनलॉक करें
- वेटिंग थ्रेड के लिए:
- म्यूटेक्स को लॉक करें
- स्टेट चर पर
whileलूप करें, जब तक डेटा तैयार न हो जाए - में
whileपाश, साथ शर्त चर पर प्रतीक्षा करpthread_cond_wait() - जब
whileपाश बाहर निकलता है, अब हम यकीन हैं कि नए डेटा के लिए तैयार है, और म्युटेक्स बंद कर दिया जाता है कि - डेटा के साथ कुछ करो
- म्यूटेक्स को अनलॉक करें और दोहराएं
इस योजना के साथ, कोई फर्क नहीं पड़ता कि सिग्नलिंग और वेटिंग थ्रेड्स शेड्यूल किए गए हैं, वेटिंग थ्रेड डेटा को कभी भी मिस नहीं करेगा (जैसा कि, यह वैध डेटा तैयार होने के साथ हमेशा के लिए इंतजार करना नहीं होगा)। यह प्रतीकात्मक धागे के चरणों के माध्यम से मैन्युअल रूप से चलाने की कोशिश करके महसूस किया जा सकता है, वेटिंग थ्रेड में प्रत्येक चरण के लिए म्यूटेक्स, स्थिति और राज्य चर के राज्यों को रिकॉर्ड कर रहा है।
pthread_cond_wait और म्यूटेक्स
उपरोक्त प्रक्रिया को सुविधाजनक बनाने के लिए, म्यूटेक्स लॉक के साथ pthread_cond_wait() कॉल करना आवश्यक है। जब कहा जाता है, pthread_cond_wait() तब थ्रेड को सोने से पहले म्यूटेक्स को अनलॉक करेगा, और, जो भी कारण के लिए लौटने से पहले, म्यूटेक्स को फिर से खोल दिया जाएगा। इसका अर्थ यह भी है कि यदि किसी अन्य धागे में वर्तमान में म्यूटेक्स लॉक है, pthread_cond_wait() म्यूटेक्स के अनलॉक होने का इंतजार करेगा, और जब तक प्रतीक्षा थ्रेड वास्तव में म्यूटेक्स को प्राप्त नहीं कर लेगा - तब तक यह किसी भी अन्य थ्रेड्स को लॉक करने की कोशिश करने के साथ-साथ इसका विरोध करेगा। एक ही समय में म्यूटेक्स।
जगमगाता हुआ जागरण
इसके अलावा, यह के रूप में अगर लग सकता है while पाश राज्य चर पर इंतज़ार कर रहे एक साधारण लिए प्रतिस्थापित किया जा सकता है if बयान। हालांकि, while पाश की जरूरत है, के रूप में POSIX मानक की अनुमति देता है pthread_cond_wait() प्रतीक्षा के दौरान तथाकथित "नकली" wakeups ऐसा करने के लिए, बिना वास्तव में संकेत जा रहा है। इस प्रकार, कोड को यह देखने के लिए राज्य चर को फिर से pthread_cond_wait() आवश्यकता है कि क्या pthread_cond_wait() वास्तव में संकेतित होने के कारण वापस आया है, या इनमें से एक भी अजीब वेकअप के कारण है।
निर्माता / उपभोक्ता उदाहरण
pthread_mutex_t queueMutex;
pthread_cond_t queueCond;
Queue queue;
void Initialize() {
//Initialize the mutex and the condition variable
pthread_mutex_init(&queueMutex, NULL);
pthread_cond_init(&queueCond, NULL);
}
void Producer() {
//First we get some new data
Data *newData = MakeNewData();
//Lock the queue mutex to make sure that adding data to the queue happens correctly
pthread_mutex_lock(&queueMutex);
//Push new data to the queue
queue.push(newData);
//Signal the condition variable that new data is available in the queue
pthread_cond_signal(&queueCond);
//Done, unlock the mutex
pthread_mutex_unlock(&queueMutex);
}
void Consumer() {
//Run the consumer loop
while(1) {
//Start by locking the queue mutex
pthread_mutex_lock(&queueMutex);
//As long as the queue is empty,
while(queue.empty()) {
// - wait for the condition variable to be signalled
//Note: This call unlocks the mutex when called and
//relocks it before returning!
pthread_cond_wait(&queueCond, &queueMutex);
}
//As we returned from the call, there must be new data in the queue - get it,
Data *newData = queue.front();
// - and remove it from the queue
queue.pop();
//Now unlock the mutex
pthread_mutex_unlock(&queueMutex);
// - and process the new data
ProcessData(newData);
}
}