2011-03-28 16 views
13

एक अनुभवहीन सवाल से Pthread Mutex ताला अनलॉक ..अलग धागे

मैं कह रहा से पहले पढ़ - "। एक म्युटेक्स धागा है कि यह बंद से केवल अनलॉक किया जा करने के लिए किया"

लेकिन मैं लिखा है एक कार्यक्रम जहां THREAD1 ताले mutexVar और नींद के लिए चला जाता है। फिर THREAD2 सीधे mutexVar अनलॉक कर सकते हैं कुछ संचालन और वापसी करते हैं।

==> मुझे पता है कि हर कोई कहता है कि मैं ऐसा क्यों कर रहा हूं ?? लेकिन मेरा सवाल है - क्या यह म्यूटेक्स का सही व्यवहार है ??

==> नमूना कोड

void *functionC() 
{ 
    pthread_mutex_lock(&mutex1); 
    counter++; 
    sleep(10); 
    printf("Thread01: Counter value: %d\n",counter); 
    pthread_mutex_unlock(&mutex1); 
} 

void *functionD() 
{ 
    pthread_mutex_unlock(&mutex1); 
    pthread_mutex_lock(&mutex1); 
    counter=10; 
    printf("Counter value: %d\n",counter); 
} 

int main() 
{ 
    int rc1, rc2; 
    pthread_t thread1, thread2; 

    if(pthread_mutex_init(&mutex1, NULL)) 
    printf("Error while using pthread_mutex_init\n"); 

    if((rc1=pthread_create(&thread1, NULL, &functionC, NULL))) 
    { 
     printf("Thread creation failed: %d\n", rc1); 
    } 

    if((rc2=pthread_create(&thread2, NULL, &functionD, NULL))) 
    { 
     printf("Thread creation failed: %d\n", rc2); 
    } 
+0

@ सैंटियागो - नमूना कोड जोड़ा गया .. – codingfreak

+0

नहीं - लेकिन 1 के मान वाला एक सेमफ़ोअर एक म्यूटेक्स की तरह हो सकता है, और इसे एक अलग थ्रेड से अनलॉक किया जा सकता है। हालांकि, 1 से ऊपर जाने वाले मूल्य को रोकने के लिए आपको म्यूटेक्स के साथ सेमफोर पर परिचालनों की रक्षा करने की आवश्यकता हो सकती है। – aaa90210

उत्तर

17

आप क्या किया है जोड़ा जा रहा है बस कानूनी नहीं है, और व्यवहार अनिर्धारित रहता है। म्यूटेक्स केवल नियमों द्वारा चलाए गए थ्रेड को बहिष्कृत करता है। यदि आपने mutex1 को थ्रेड 2 से लॉक करने का प्रयास किया है, तो थ्रेड अवरुद्ध हो जाएगा; यह करने के लिए आवश्यक चीज है। कल्पना में कुछ भी नहीं है जो कहता है कि क्या होता है यदि आप एक म्यूटेक्स को अनलॉक करने का प्रयास करते हैं जो आपके पास नहीं है!

+0

उत्तर के लिए धन्यवाद। लेकिन जब मूल बातें कहती हैं कि थ्रेड 2 थ्रेड 1 द्वारा आयोजित म्यूटेक्स को अनलॉक नहीं कर सकता है तो पीटीएचड के कार्यान्वयन क्यों भिन्न होते हैं ?? – codingfreak

+24

@ कोडिंगफ्रैक: एपीआई एक सीधा नहीं है। दस्तावेज कह रहा है "ऐसा मत करो", नहीं "हम आपको सक्रिय रूप से ऐसा करने से रोक देंगे"। कंप्यूटर हमेशा उन चीजों को करने से नहीं रोकते हैं जिन्हें आप नहीं मानते हैं। यह एक काफी बुनियादी अवधारणा है जो आप सीखते समय बार-बार आती है: आप सभी प्रकार की चीजें कर सकते हैं, उनमें से कई चीजें जिन्हें आप नहीं मानते हैं, और यदि आपके द्वारा किए गए व्यवहार को अपरिभाषित किया गया है। यह कहने जैसा है "आपको नशे में ड्राइव करने की अनुमति नहीं है" - ऐसा कोई तंत्र सक्रिय रूप से ऐसा करने से आपको रोक नहीं रहा है, लेकिन आपको अभी भी ऐसा करने की आवश्यकता नहीं है। –

+0

आप दोनों को +1, दोस्तों। अच्छी व्याख्याएं! – slezica

19

पर्थ्रेड में 3 अलग-अलग प्रकार के म्यूटेक्स हैं: फास्ट म्यूटेक्स, रिकर्सिव म्यूटेक्स, और त्रुटि जांच mutex। आपने एक तेज म्यूटेक्स का उपयोग किया जो प्रदर्शन कारणों से, इस त्रुटि की जांच नहीं करेगा। यदि आप लिनक्स पर त्रुटि जांच mutex का उपयोग करते हैं तो आप पाएंगे कि आपको वह परिणाम मिलते हैं जिन्हें आप उम्मीद करते हैं।

नीचे आपके कार्यक्रम का एक छोटा सा हैक उदाहरण और सबूत के रूप में है। यह मुख्य() में mutex को लॉक करता है और बनाए गए थ्रेड में अनलॉक विफल हो जाएगा।

#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <errno.h> 
#include <stdlib.h> 

/*** NOTE THE ATTR INITIALIZER HERE! ***/ 
pthread_mutex_t mutex1 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; 

int counter = 0; 


void *functionD(void* data) 
{ 
    int rc; 

    if ((rc = pthread_mutex_unlock(&mutex1)) != 0) 
    { 
     errno = rc; 
     perror("other thread unlock result"); 
     exit(1); 
    } 

    pthread_mutex_lock(&mutex1); 
    counter=10; 
    printf("Thread02: Counter value: %d\n",counter); 

    return(data); 
} 


int main(int argc, char *argv[]) 
{ 
    int rc1; 
    pthread_t thread1; 

    if ((rc1 = pthread_mutex_lock(&mutex1)) != 0) 
    { 
     errno = rc1; 
     perror("main lock result"); 
    } 

    if((rc1 = pthread_create(&thread1, NULL, &functionD, NULL))) 
    { 
     printf("Thread creation failed: %d\n", rc1); 
    } 

    pthread_join(thread1, NULL); 
} 
+3

लिनक्स पर -D_GNU_SOURCE के साथ संकलित करें। – Lupus

-2

एक म्युटेक्स कोड है कि एक समय में एक थ्रेड के लिए केवल सुरक्षित है क्रियान्वित करने से एक से अधिक थ्रेड को रोकने के लिए प्रयोग किया जाता है।

ऐसा करने के लिए एक म्युटेक्स कई सुविधाएं होती हैं:

  1. एक म्युटेक्स एक से अधिक थ्रेड एक ही समय में म्युटेक्स "ताला" की कोशिश कर रहा है और हमेशा के साथ जुड़े दौड़ की स्थिति संभाल कर सकते हैं एक धागा जीतने के साथ परिणाम दौड़।

  2. किसी भी थ्रेड जो दौड़ को खो देता है उसे म्यूटेक्स अनलॉक होने तक स्थायी रूप से सो जाता है। म्यूटेक्स इन धागे की एक सूची बनाए रखता है।

  3. ए एक "लॉक" को एक और केवल प्रतीक्षा धागे को सौंप देगा जब म्यूटेक्स को थ्रेड द्वारा अनलॉक किया जाएगा जो इसका उपयोग कर रहा था। म्यूटेक्स उस थ्रेड को जगाएगा।

यदि उस प्रकार का पैटर्न किसी अन्य उद्देश्य के लिए उपयोगी है तो आगे बढ़ें और इसे किसी अन्य कारण से उपयोग करें।

अपने प्रश्न पर वापस जाएं। आइए कहें कि आप म्यूटेक्स के साथ कई थ्रेड एक्सेस से कुछ कोड की रक्षा कर रहे थे और कहें कि 5 थ्रेड प्रतीक्षा कर रहे थे जबकि थ्रेड ए कोड को निष्पादित कर रहा था। यदि थ्रेड बी (उन लोगों में से एक नहीं है क्योंकि वे इस समय स्थायी रूप से सोए जाते हैं) म्यूटेक्स को अनलॉक करते हैं, तो एक और थ्रेड उसी समय कोड को निष्पादित करना शुरू कर देगा जैसे कि शायद ए वांछित नहीं है।

शायद अगर हम जानते थे कि आप म्यूटेक्स का उपयोग करने के बारे में क्या सोच रहे थे, तो हम बेहतर जवाब दे सकते थे। क्या आप धागे को रद्द करने के बाद एक म्यूटक्स अनलॉक करने का प्रयास कर रहे हैं?क्या आपके पास कोड है जो एक समय में 2 धागे को संभाल सकता है लेकिन तीन नहीं और कोई म्यूटेक्स नहीं है जो एक समय में 2 धागे को देता है?

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