2012-06-14 8 views
6

विशेष रूप से पाथ्रेड के मामले में उन्हें कैसे लागू किया जाता है। क्या pthread सिंक्रनाइज़ेशन एपीआई वे हुड के तहत उपयोग करते हैं? छद्म कोड का थोड़ा सा सराहना की जाएगी।पठ्रेड में लागू ताले पढ़ने/लिखने वाले ताले कैसे हैं?

+7

शायद आप तेह codez पढ़ सकें? – tbert

+1

शायद [यह] (http: //www.cognitus।नेट/एचटीएमएल/howto/pthreadSemiFAQ_10.html) मदद कर सकते हैं? –

उत्तर

8

मैंने थोड़ी देर के लिए प्रोग्रामिंग नहीं किया है, लेकिन जब मैंने किया, तो मैंने कभी भी पॉज़िक्स को पढ़ने/लिखने वाले ताले का उपयोग नहीं किया। समस्या यह है कि ज्यादातर समय एक म्यूटेक्स पर्याप्त होगा: यानी। आपका महत्वपूर्ण खंड छोटा है, और यह क्षेत्र इतना महत्वपूर्ण नहीं है कि डबल बाधा चिंताजनक है।

उन मामलों में जहां प्रदर्शन एक मुद्दा है, आम तौर पर परमाणु संचालन (आमतौर पर एक कंपाइलर एक्सटेंशन के रूप में उपलब्ध) का उपयोग करना एक बेहतर विकल्प होता है (यानी अतिरिक्त बाधा समस्या है, महत्वपूर्ण खंड का आकार नहीं)।

जब तक आप इन सभी मामलों को खत्म नहीं करते हैं, तब तक आपको ऐसे मामलों के साथ छोड़ दिया जाता है जहां आपके पास विशिष्ट प्रदर्शन/निष्पक्षता/आरडब्ल्यू-पूर्वाग्रह आवश्यकता होती है जिसके लिए एक वास्तविक आरडब्ल्यू-लॉक की आवश्यकता होती है; और यह तब होता है जब आप पाते हैं कि POSIX आरडब्ल्यू-लॉक के सभी प्रासंगिक प्रदर्शन/निष्पक्षता पैरामीटर अनिर्धारित हैं और कार्यान्वयन विशिष्ट हैं। इस बिंदु पर आप आम तौर पर अपने आप को लागू करने से बेहतर होते हैं ताकि आप सुनिश्चित कर सकें कि उचित निष्पक्षता/आरडब्ल्यू-पूर्वाग्रह आवश्यकताओं को पूरा किया जा सके।

बुनियादी एल्गोरिथ्म कैसे प्रत्येक के कई महत्वपूर्ण अनुभाग में हैं की गणना करने के लिए है, और एक धागा अभी तक पहुँच की अनुमति नहीं है, तो यह एक उचित कतार में बंद अलग धकेलना करने के लिए प्रतीक्षा करने के लिए। आपके अधिकांश प्रयास दो कतारों की सेवा के बीच उपयुक्त निष्पक्षता/पूर्वाग्रह को लागू करने में होंगे।

निम्नलिखित सी-जैसे pthreads- जैसे छद्म कोड बताता है कि मैं क्या कहने की कोशिश कर रहा हूं।

struct rwlock { 
    mutex admin; // used to serialize access to other admin fields, NOT the critical section. 
    int count; // threads in critical section +ve for readers, -ve for writers. 
    fifoDequeue dequeue; // acts like a cond_var with fifo behaviour and both append and prepend operations. 
    void *data; // represents the data covered by the critical section. 
} 

void read(struct rwlock *rw, void (*readAction)(void *)) { 
    lock(rw->admin); 
    if (rw->count < 0) { 
    append(rw->dequeue, rw->admin); 
    } 
    while (rw->count < 0) { 
    prepend(rw->dequeue, rw->admin); // Used to avoid starvation. 
    } 
    rw->count++; 
    // Wake the new head of the dequeue, which may be a reader. 
    // If it is a writer it will put itself back on the head of the queue and wait for us to exit. 
    signal(rw->dequeue); 
    unlock(rw->admin); 

    readAction(rw->data); 

    lock(rw->admin); 
    rw->count--; 
    signal(rw->dequeue); // Wake the new head of the dequeue, which is probably a writer. 
    unlock(rw->admin); 
} 

void write(struct rwlock *rw, void *(*writeAction)(void *)) { 
    lock(rw->admin); 
    if (rw->count != 0) { 
    append(rw->dequeue, rw->admin); 
    } 
    while (rw->count != 0) { 
    prepend(rw->dequeue, rw->admin); 
    } 
    rw->count--; 
    // As we only allow one writer in at a time, we don't bother signaling here. 
    unlock(rw->admin); 

    // NOTE: This is the critical section, but it is not covered by the mutex! 
    //  The critical section is rather, covered by the rw-lock itself. 
    rw->data = writeAction(rw->data); 

    lock(rw->admin); 
    rw->count++; 
    signal(rw->dequeue); 
    unlock(rw->admin); 
} 

उपरोक्त कोड की तरह कुछ किसी भी rwlock कार्यान्वयन के लिए एक प्रारंभिक बिंदु है। अपनी समस्या की प्रकृति को कुछ विचार दें और उचित तर्क के साथ डेक्यू को प्रतिस्थापित करें जो निर्धारित करता है कि थ्रेड के किस वर्ग को आगे जगाया जाना चाहिए। एप्लिकेशन के आधार पर पाठकों की सीमित संख्या/पाठकों को लेखकों या वीज़ा के विपरीत छलांग लगाने की अनुमति देना आम बात है।

बेशक

मेरी सामान्य वरीयता rw-ताले पूरी तरह से बचने के लिए है, आम तौर पर परमाणु संचालन, म्यूटेक्स, एसटीएम, संदेश-पासिंग, और लगातार डेटा संरचनाओं के कुछ संयोजन का उपयोग करके। हालांकि ऐसे समय होते हैं जब आपको वास्तव में एक आरडब्ल्यू-लॉक की आवश्यकता होती है, और जब आप ऐसा करते हैं तो यह जानना उपयोगी होता है कि वे कैसे काम करते हैं, इसलिए मुझे उम्मीद है कि इससे मदद मिलेगी।

संपादित करें - (बहुत ही उचित) प्रश्न है, जहां मैं ऊपर छद्म कोड में इंतजार करना के जवाब में:

मैं मान लिया है विपंक्ति कार्यान्वयन इंतजार होता है, ताकि append(dequeue, mutex) या prepend(dequeue, mutex) कहीं भीतर

while(!readyToLeaveQueue()) { 
    wait(dequeue->cond_var, mutex); 
} 

जो था कारण है कि मैं कतार संचालन के लिए प्रासंगिक म्युटेक्स में पारित: की तर्ज पर कोड का एक खंड है।

+0

क्या आप आरडब्ल्यू ताले से बचने के लिए और कैसे विस्तृत विवरण के बारे में बता सकते हैं? मैं उन स्थानों पर pthread आरडब्ल्यू ताले का उपयोग कर रहा हूं जहां मुझे लगता है कि मुझे नहीं होना चाहिए और आप किस बारे में बात कर रहे हैं इसके बारे में अधिक जानना चाहते हैं। – puffadder

+0

यह आरडब्ल्यू ताले से बचने के बारे में नहीं है। जैसा कि मैंने अपने जवाब में कहा था, जब आपको आरडब्ल्यू लॉक की आवश्यकता होती है तो आपको एक का उपयोग करना चाहिए। समस्या यह है कि आरडब्ल्यू लॉक की आवश्यकता होती है और पूर्वाग्रह/निष्पक्षता की आवश्यकता भी नहीं होती है। पॉज़िक्स आरडब्ल्यू ताले कोई पूर्वाग्रह/निष्पक्षता गारंटी नहीं देते हैं, और ऐसे समय के लिए विडंबनात्मक रूप से गैर-पोर्टेबल हैं जहां आप उनका उपयोग करना चाहेंगे। यह देखते हुए कि अपने पोर्टेबल आरडब्ल्यू लॉक को लागू करना मुश्किल नहीं है, आप भी हो सकते हैं। – Recurse

+0

आप कोड में सिग्नल के लिए कहां इंतजार करते हैं। मैं कई स्थानों पर सिग्नल (आरडब्ल्यू-> डेक) देखता हूं, लेकिन उस सिग्नल पर इंतजार करने के लिए कोई कोड नहीं है। – pythonic

0

प्रत्येक कार्यान्वयन अलग-अलग हो सकता है, लेकिन आम तौर पर उन्हें पॉज़िक्स द्वारा आवश्यकता के कारण पाठकों को डिफ़ॉल्ट रूप से पक्षपात करना पड़ता है कि एक धागा कई बार एक rwlock पर रीड-लॉक प्राप्त करने में सक्षम होता है। अगर वे लेखकों का पक्ष लेते हैं, तो जब भी कोई लेखक इंतजार कर रहा था, पाठक दूसरे रीड-लॉक प्रयास पर डेडलॉक करेगा जब तक कि कार्यान्वयन निर्धारित नहीं कर सके कि पाठक के पास पहले से ही एक रीड लॉक है, लेकिन यह निर्धारित करने का एकमात्र तरीका है कि सभी धागे की सूची संग्रहित करना जो ताले पढ़ने वाले हैं, जो समय और अंतरिक्ष आवश्यकताओं में बहुत अक्षम हैं।

+1

आपकी टिप्पणी केवल पुनर्विक्रेता आरडब्ल्यू-ताले पर लागू होती है। जैसा कि मेरे उत्तर में दिखाया गया है, गैर-पुनर्वित्त ताले केवल एक गिनती की आवश्यकता है। इसके अलावा, एक सूची पुनर्वित्त को लागू करने के लिए डेटा संरचना की एक बहुत ही खराब पसंद है। लघु सरणी, बिटमैप्स, और रैखिक-हैशटेबल्स का कैश-सचेत संयोजन बहीखाता को और अधिक स्थान/समय कुशल बना सकता है। – Recurse

+0

पुनर्विक्रेता द्वारा आप का मतलब रिकर्सिव है? रिकेंट्रेंसी केवल रिकर्सिव लॉकिंग की तुलना में एक बहुत मजबूत आवश्यकता है। –