2012-10-22 19 views
5

हैलो, मैं बहु-थ्रेड प्रोग्रामिंग के लिए नया हूं। मैं एक कोड बनाने की कोशिश कर रहा हूं जो थ्रेड THREAD1 बनाता है, कि, कुछ करने के बाद, यह दो अन्य धागे ट्रिगर करता है, THREAD2 और THREAD3 कहता है, और फिर बाहर निकलता है।pthreads: एक थ्रेड जो अन्य धागे को ट्रिगर करता है

मैंने दो संभावित समाधान लिखे।

1) हालत चर का उपयोग करें (काम नहीं करता है: कुछ मामले में मैं एक गतिरोध प्राप्त):

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 
bool ready = false; 

void* trigger(void*); 
void* func1(void*); 
void* func2(void*); 

int main() 
{ 
    pthread_t thread1; 
    pthread_t thread2; 
    pthread_t thread3; 
    pthread_create(&thread1, 0, &trigger, 0); 
    pthread_create(&thread2, 0, &func1, 0); 
    pthread_create(&thread3, 0, &func2, 0); 
    pthread_join(thread1, 0); 
    pthread_join(thread2, 0); 
    pthread_join(thread3, 0); 
} 

void *trigger(void*) 
{ 
    pthread_mutex_lock(&ready_mutex); 
    ready = true; 
    pthread_cond_broadcast(&ready_cond); 
    pthread_mutex_unlock(&ready_mutex); 
    return 0; 
} 

void *func1(void*) 
{ 
    while (!ready) // Needed to avoid spuriuos wake-up 
    { 
     pthread_mutex_lock(&ready_mutex); 
     pthread_cond_wait(&ready_cond, &ready_mutex); 
     pthread_mutex_unlock(&ready_mutex); 
    } 
    std::cout << "In 'func1'>> Do something" << std::endl; 
    return 0; 
} 

void *func2(void*) 
{ 
    while (!ready) // Needed to avoid spuriuos wake-up 
    { 
     pthread_mutex_lock(&ready_mutex); 
     pthread_cond_wait(&ready_cond, &ready_mutex); 
     pthread_mutex_unlock(&ready_mutex); 
    } 
    std::cout << "In 'func2'>> Do something" << std::endl; 
    return 0; 
} 

2) THREAD1 सीधे दो अन्य धागे पैदा करता है।

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 

pthread_t thread1; 
pthread_t thread2; 
pthread_t thread3; 

void* trigger(void*); 
void* func1(void*); 
void* func2(void*); 

int main() 
{ 
    pthread_create(&thread1, 0, &trigger, 0); 

    pthread_join(thread1, 0); 
    pthread_join(thread2, 0); 
    pthread_join(thread3, 0); 
} 

void *trigger(void*) 
{ 
    std::cout << "In 'trigger'>> Do something" << std::endl; 

    pthread_create(&thread2, 0, &func1, 0); 
    pthread_create(&thread3, 0, &func2, 0); 

    return 0; 
} 

void *func1(void*) 
{ 
    std::cout << "In 'func1'>> Do something" << std::endl; 

    return 0; 
} 

void *func2(void*) 
{ 
    std::cout << "In 'func2'>> Do something" << std::endl; 

    return 0; 
} 

मैं आपकी राय जानना चाहते हैं। आपको बहुत बहुत धन्यवाद

हालत चर के
+0

आपका दूसरा कार्यान्वयन ठीक काम करता प्रतीत होता है, आपको क्या लगता है कि इसमें गलत है? – engineerC

+0

आपका दूसरा विकल्प क्लीनर और अच्छा है। मैं वह करूँगा –

+0

@ कैप्टनमर्फी: मुझे आश्चर्य है कि इस लक्ष्य तक पहुंचने का एक बेहतर तरीका है या नहीं। POSIX मैन्युअल पृष्ठों से, ऐसा लगता है कि हालत चर इस उद्देश्य के लिए बेहतर अनुकूल हैं क्योंकि इन्हें किसी विशेष घटना के लिए सिग्नल करने के लिए उपयोग किया जा सकता है। –

उत्तर

5

उपयोग करें (काम करते हुए नहीं: कुछ मामले में मैं एक गतिरोध प्राप्त):

जब साझा की स्थिति की जाँच के कोड म्युटेक्स लॉक नहीं करता परिवर्तनीय ready। जब यह mutex ready लॉक करता है तो उस समय तक अच्छी तरह से बदल सकता है, यही कारण है कि आप deadlocks देखते हैं।

सही संस्करण एक शर्त चर के साथ स्थिति परिवर्तन के लिए इंतजार करना है (त्रुटि लोप जाँच):

pthread_mutex_lock(&ready_mutex); 
while(!ready) // Needed to avoid spuriuos wake-up 
    pthread_cond_wait(&ready_cond, &ready_mutex); 
// ready == true here 
pthread_mutex_unlock(&ready_mutex); 

ऊपर मानता है कि ready में कभी भी परिवर्तन तभी होता है जब एक ही म्युटेक्स आयोजित किया जाता है।

+0

हाँ, आप सही हैं। तो, मेरे प्रश्न पर लौटने पर, क्या मुझे हालत चर (समाधान # 1) या स्थगित धागा निर्माण (समाधान # 2) का उपयोग करना चाहिए? –

+1

@ seg.fault मैं [ओकम के रेज़र] का उपयोग करता हूं (http://en.wikipedia.org/wiki/Occam's_razor): किसी समस्या के लिए कई समाधान दिए गए सरल को चुनते हैं। –

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