2012-12-02 14 views
9

मैं 2 थ्रेड के लिए pthread_cond_wait लागू करने की कोशिश कर रहा हूं।2 थ्रेड के लिए pthread_cond_wait

  • थ्रेड बी इंतजार हालत के लिए
  • थ्रेड एक प्रिंट "हैलो" पांच बार
  • थ्रेड एक संकेत धागा
  • थ्रेड एक: मेरे परीक्षण कोड इस परिदृश्य पर पहिले से दो धागे का उपयोग करने की कोशिश कर रहा है
  • थ्रेड बी प्रिंट "गुडबाय"
  • थ्रेड बी संकेतों थ्रेड
  • लूप शुरू करने के लिए (x5)
  • इंतजार कर रहा है

अब तक कोड पांच बार "हैलो" प्रिंट करता है और फिर अटक जाता है। उदाहरण से मैं देखा है ऐसा लगता है पर मैं सही रास्ते पर हूँ "लॉक म्युटेक्स, रुको, अन्य धागा द्वारा संकेत मिलता है, म्युटेक्स अनलॉक, सामान, पाश करना"

टेस्ट कोड:

//Import 
#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <unistd.h> 

//global variables 
pthread_cond_t  condA = PTHREAD_COND_INITIALIZER; 
pthread_cond_t  condB = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER; 




void *threadA() 
{ 
    int i = 0, rValue, loopNum; 

    while(i<5) 
    { 
     //unlock mutex 
     rValue = pthread_mutex_unlock(&mutex); 

     //do stuff 
     for(loopNum = 1; loopNum <= 5; loopNum++) 
      printf("Hello %d\n", loopNum); 

     //signal condition of thread b 
     rValue = pthread_cond_signal(&condB); 

     //lock mutex 
     rValue = pthread_mutex_lock(&mutex); 

     //wait for turn 
     while(pthread_cond_wait(&condA, &mutex) != 0) 

     i++; 
    } 

} 



void *threadB() 
{ 
    int n = 0, rValue; 

    while(n<5) 
    { 
     //lock mutex 
     rValue = pthread_mutex_lock(&mutex); 

     //wait for turn 
     while(pthread_cond_wait(&condB, &mutex) != 0) 

     //unlock mutex 
     rValue = pthread_mutex_unlock(&mutex); 

     //do stuff 
     printf("Goodbye"); 

     //signal condition a 
     rValue = pthread_cond_signal(&condA); 

     n++;   
    } 
} 




int main(int argc, char *argv[]) 
{ 
    //create our threads 
    pthread_t a, b; 

    pthread_create(&a, NULL, threadA, NULL); 
    pthread_create(&b, NULL, threadB, NULL); 

    pthread_join(a, NULL); 
    pthread_join(b,NULL); 
} 

सही दिशा में एक सूचक की बहुत सराहना की जाएगी, धन्यवाद! ("gcc timeTest.c -o timeTest -lpthread" का उपयोग कर लिनक्स पर संकलित कोड)

+0

नहीं, इसकी आवश्यकता नहीं है, मैं मुख्य रूप से भिन्नताओं की कोशिश कर रहा था लेकिन जैसा कि आपने कहा था कि यह केवल –

उत्तर

28

आपके पास दो समस्याएं हैं। उदाहरण के लिए, यहाँ - पहला यह है कि आप while() छोरों सही ढंग से उपयोग कर रहे हैं नहीं है:

//wait for turn 
while(pthread_cond_wait(&condA, &mutex) != 0) 

i++; 

while पाश के शरीर बयान i++ है - इस pthread_cond_wait() और i++ निष्पादित करेंगे जब तक pthread_cond_wait() एक त्रुटि देता है, तो यह अनिवार्य रूप से एक अंतहीन पाश है।

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

//global variables 
/* STATE_A = THREAD A runs next, STATE_B = THREAD B runs next */ 
enum { STATE_A, STATE_B } state = STATE_A; 
pthread_cond_t  condA = PTHREAD_COND_INITIALIZER; 
pthread_cond_t  condB = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER; 

void *threadA() 
{ 
    int i = 0, rValue, loopNum; 

    while(i<5) 
    { 
     /* Wait for state A */ 
     pthread_mutex_lock(&mutex); 
     while (state != STATE_A) 
      pthread_cond_wait(&condA, &mutex); 
     pthread_mutex_unlock(&mutex); 

     //do stuff 
     for(loopNum = 1; loopNum <= 5; loopNum++) 
      printf("Hello %d\n", loopNum); 

     /* Set state to B and wake up thread B */ 
     pthread_mutex_lock(&mutex); 
     state = STATE_B; 
     pthread_cond_signal(&condB); 
     pthread_mutex_unlock(&mutex); 

     i++; 
    } 

    return 0; 
} 

void *threadB() 
{ 
    int n = 0, rValue; 

    while(n<5) 
    { 
     /* Wait for state B */ 
     pthread_mutex_lock(&mutex); 
     while (state != STATE_B) 
      pthread_cond_wait(&condB, &mutex); 
     pthread_mutex_unlock(&mutex); 

     //do stuff 
     printf("Goodbye\n"); 

     /* Set state to A and wake up thread A */ 
     pthread_mutex_lock(&mutex); 
     state = STATE_A; 
     pthread_cond_signal(&condA); 
     pthread_mutex_unlock(&mutex); 

     n++; 
    } 

    return 0; 
} 

ध्यान दें कि दो शर्त चर condA और condB के उपयोग यहाँ अनावश्यक है - कोड बस के रूप में सही हो, तो केवल एक ही शर्त चर के बजाय इस्तेमाल किया गया था होगा।

+4

आह का उपयोग करने के लिए आदर्श होगा, जबकि लूप के साथ गलती की गलती! साझा राज्यों के उपयोग के बारे में इनपुट के लिए धन्यवाद, मैं इसके उपयोग के पीछे तर्क समझता हूं।एक शर्त कंडीशन वैरिएबल के उपयोग के संबंध में, मैं जो कह रहा हूं उससे पूरी तरह से सहमत हूं। प्रतिक्रिया के लिए बहुत कुछ, बड़ी परियोजना को कोड करने का समय, विस्तृत प्रतिक्रिया के लिए फिर से धन्यवाद! –

+1

+1 साझा-राज्य (जिसे अक्सर 'predicate' कहा जाता है) का अच्छा वर्णन है कि cvar-mtx जोड़े को प्रबंधित करने के लिए डिज़ाइन किया गया है। – WhozCraig

0

कोड वास्तव में लगभग मेरी मशीन पर ठीक काम करता है जब आप थोड़ी देर के लिए घुंघराले ब्रेसिज़ जोड़ते हैं।

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

आप पंक्ति 47 पर usleep(1) का उपयोग करके कलात्मक देरी पेश कर सकते हैं और खुद के लिए देख सकते हैं।

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