2013-02-15 69 views
17

बहु थ्रेडेड/प्रोसेस प्रोग्रामिंग में नया हूं। तो यहां मुझे स्पष्टीकरण देने की आवश्यकता है।म्यूटेक्स लॉक थ्रेड्स

प्रक्रिया एक कोड

pthread_mutex_lock() 
    pthread_create(fooAPI(sharedResource)) //fooAPI creates another thread with shared resource that shares across processes. 
pthread_mutex_unlock() 
ऊपर छद्म कोड के साथ

, प्रक्रिया बी sharedResource उपयोग करने के लिए करता है, तो म्युटेक्स अनलॉक नहीं है में सक्षम है?

मैं प्रक्रिया बी से साझा संसाधन को कैसे सही तरीके से एक्सेस कर सकता हूं?

कोई भी कोई स्पष्ट दृश्य चित्र जो म्यूटेक्स, धागे और प्रक्रियाओं के बीच संबंध बताता है?

उत्तर

30

आप क्या करने की जरूरत एक म्युटेक्स सुरक्षित करने के लिए, इस तरह pthread_mutex_lock कॉल करने के लिए है:

pthread_mutex_lock(&mutex); 

एक बार जब आप ऐसा करते हैं, pthread_mutex_lock(mutex) के लिए किसी भी अन्य कॉल वापस नहीं होगा, जब तक आप इस थ्रेड के pthread_mutex_unlock कहते हैं। तो यदि आप pthread_create को कॉल करने का प्रयास करते हैं, तो आप एक नया थ्रेड बनाने में सक्षम होंगे, और वह थ्रेड साझा संसाधन का उपयोग करने में (गलत तरीके से) सक्षम होगा। आपको अपने fooAPI फ़ंक्शन के भीतर pthread_mutex_lock पर कॉल करना चाहिए, और इससे साझा संसाधन उपलब्ध होने तक फ़ंक्शन का इंतजार करना पड़ेगा।

#include <pthread.h> 
#include <stdio.h> 

int sharedResource = 0; 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 

void* fooAPI(void* param) 
{ 
    pthread_mutex_lock(&mutex); 
    printf("Changing the shared resource now.\n"); 
    sharedResource = 42; 
    pthread_mutex_unlock(&mutex); 
    return 0; 
} 

int main() 
{ 
    pthread_t thread; 

    // Really not locking for any reason other than to make the point. 
    pthread_mutex_lock(&mutex); 
    pthread_create(&thread, NULL, fooAPI, NULL); 
    sleep(1); 
    pthread_mutex_unlock(&mutex); 

    // Now we need to lock to use the shared resource. 
    pthread_mutex_lock(&mutex); 
    printf("%d\n", sharedResource); 
    pthread_mutex_unlock(&mutex); 
} 

संपादित करें::

तो तुम कुछ इस तरह होता है यह एक ही बुनियादी दृष्टिकोण इस प्रकार की प्रक्रिया में संसाधनों का उपयोग करते हुए, लेकिन आप अपने अन्य प्रक्रिया में स्मृति मैप करने के लिए की जरूरत है। यहाँ एक उदाहरण का उपयोग करते हुए shmem है:

#include <stdio.h> 
#include <unistd.h> 
#include <sys/file.h> 
#include <sys/mman.h> 
#include <sys/wait.h> 

struct shared { 
    pthread_mutex_t mutex; 
    int sharedResource; 
}; 

int main() 
{ 
    int fd = shm_open("/foo", O_CREAT | O_TRUNC | O_RDWR, 0600); 
    ftruncate(fd, sizeof(struct shared)); 

    struct shared *p = (struct shared*)mmap(0, sizeof(struct shared), 
     PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 

    p->sharedResource = 0; 

    // Make sure it can be shared across processes 
    pthread_mutexattr_t shared; 
    pthread_mutexattr_init(&shared); 
    pthread_mutexattr_setpshared(&shared, PTHREAD_PROCESS_SHARED); 

    pthread_mutex_init(&(p->mutex), &shared); 

    int i; 
    for (i = 0; i < 100; i++) { 
     pthread_mutex_lock(&(p->mutex)); 
     printf("%d\n", p->sharedResource); 
     pthread_mutex_unlock(&(p->mutex)); 
     sleep(1); 
    } 

    munmap(p, sizeof(struct shared*)); 
    shm_unlink("/foo"); 
} 

कार्यक्रम p- में परिवर्तन करने का लेखन> sharedResource पाठक के लिए एक व्यायाम के रूप में छोड़ दिया जाता है। :-)

ध्यान दें कि, mutex को PTHREAD_PROCESS_SHARED विशेषता सेट होना चाहिए, ताकि pthreads प्रक्रियाओं में काम करे।

+0

यह बहुत स्पष्ट है। क्या आप एक उदाहरण भी शामिल कर सकते हैं कि प्रोसेस बी जो एक और एप्लीकेशन है, साझा संसाधन को एक्सेस कर सकता है? – resting

2

क्यू 1।) मान लीजिए बी बी प्रक्रिया में लॉक किए गए उसी म्यूटेक्स के स्वामित्व को लेने की कोशिश करता है ए (आपने इसे अपने छद्म कोड से बाहर छोड़ दिया है) तो नहीं, प्रक्रिया बी साझा संसाधन तक नहीं पहुंच सकती है, जबकि म्यूटेक्स लॉक हो जाता है क्योंकि यह प्रतीक्षा कर बैठेगा mutex को लॉक करने के लिए जब तक यह mutex लॉक नहीं होता है (या जब कोई त्रुटि होती है!)

प्रश्न 2) प्रक्रिया बी में, सुनिश्चित करें कि आप हमेशा लॉक करें mutex, साझा संसाधन का उपयोग करें, और उसके बाद mutex अनलॉक करें। साथ ही, mutex_lock (pMutex) दिनचर्या से रिटर्न कोड जांचें ताकि यह सुनिश्चित किया जा सके कि आप वास्तव में म्यूटेक्स के स्वामी हैं, और यदि आपने इसे लॉक किया है तो केवल म्यूटेक्स को अनलॉक करें। प्रक्रिया ए

म्यूटेक्स तक पहुंचने पर दोनों प्रक्रियाओं को मूल रूप से वही करना चाहिए।
ताला() ताला, सफल होता है तो, तो { पहुँच sharedResource अनलॉक() }

Q3) हाँ, वहाँ चित्र के बहुत सारे हैं:। =) https://www.google.se/search?q=mutex+thread+process&rlz=1C1AFAB_enSE487SE487&um=1&ie=UTF-8&hl=en&tbm=isch&source=og&sa=N&tab=wi&ei=ErodUcSmKqf54QS6nYDoAw&biw=1200&bih=1730&sei=FbodUbPbB6mF4ATarIBQ

1

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

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

2

नीचे, कोड स्निपेट, आपको म्यूटेक्स-लॉक-अनलॉक अवधारणा को समझने में मदद करेगा। कोड पर सूखी दौड़ का प्रयास करें। (प्रतीक्षा-समय और प्रक्रिया-समय को बदलकर आगे, आप समझ सकते हैं)। आपके संदर्भ के लिए

कोड:

#include <stdio.h> 
#include <pthread.h> 

void in_progress_feedback(int); 

int global = 0; 
pthread_mutex_t mutex; 
void *compute(void *arg) { 

    pthread_t ptid = pthread_self(); 
    printf("ptid : %08x \n", (int)ptid);  

    int i; 
    int lock_ret = 1; 
    do{ 

     lock_ret = pthread_mutex_trylock(&mutex); 
     if(lock_ret){ 
      printf("lock failed(%08x :: %d)..attempt again after 2secs..\n", (int)ptid, lock_ret); 
      sleep(2); //wait time here.. 
     }else{ //ret =0 is successful lock 
      printf("lock success(%08x :: %d)..\n", (int)ptid, lock_ret); 
      break; 
     } 

    } while(lock_ret); 

     for (i = 0; i < 10*10 ; i++) 
     global++; 

    //do some stuff here 
    in_progress_feedback(10); //processing-time here.. 

    lock_ret = pthread_mutex_unlock(&mutex); 
    printf("unlocked(%08x :: %d)..!\n", (int)ptid, lock_ret); 

    return NULL; 
} 

void in_progress_feedback(int prog_delay){ 

    int i=0; 
    for(;i<prog_delay;i++){ 
    printf(". "); 
    sleep(1); 
    fflush(stdout); 
    } 

    printf("\n"); 
    fflush(stdout); 
} 

int main(void) 
{ 
    pthread_t tid0,tid1; 
    pthread_mutex_init(&mutex, NULL); 
    pthread_create(&tid0, NULL, compute, NULL); 
    pthread_create(&tid1, NULL, compute, NULL); 
    pthread_join(tid0, NULL); 
    pthread_join(tid1, NULL); 
    printf("global = %d\n", global); 
    pthread_mutex_destroy(&mutex); 
      return 0; 
} 
+0

क्या फ़ंक्शन शून्य * गणना() केवल कॉल होने पर निष्पादित हो जाती है या क्या इस धागे को लॉन्च करने का कोई तरीका है, इसलिए यह पृष्ठभूमि में इस फ़ंक्शन को लगातार निष्पादित करता है? – LandonZeKepitelOfGreytBritn

+0

जब कोई थ्रेड उत्पन्न होता है, तो स्प्रेड किए गए थ्रेड के साथ बाध्य विधि थ्रेड पर निष्पादित होती है (इस मामले में 'गणना() ')। यदि कोई धागा पैदा नहीं हुआ है, तो आप अभी भी मुख्य धागे पर हैं (जहां 'मुख्य()' निष्पादित होते हैं)। अब, अगर आपको थ्रेड को पृष्ठभूमि में कुछ करना है, तो आपको कुछ गैर-निकास की स्थिति (यानी बाध्य विधि से बाहर निकलने की अनुमति न दें, जब तक आप बंद करने के लिए नहीं कहें, बाध्य विधि पर निष्पादन को पकड़ने की आवश्यकता है। अब, थ्रेड पर संकेत दिए जाने पर निकास की स्थिति, इसे बाहर निकलना चाहिए (सफाई आदि), अन्यथा यह आपके इच्छित ऑपरेशन/प्रदर्शन करने के लिए रहेगा। – parasrish