2010-03-24 17 views
5

मेरे पास एक गतिशील बहुप्रचारित कार्यक्रम है जिसमें वृक्ष संरचना में डेटा शामिल है। निम्नानुसार कार्यान्वित:वृक्ष संरचनाएं और धागे

typedef struct 
{ 
    // data pertaining to linkages, defining the architecture of the tree 
    int parent_node; 
    int child_node[MAX_CHILD_NODES]; 
    int number_of_children; 

    // data pertaining to info at each node 
    float interesting_info_A; 
    char interesting_info_B[STRING_LEN]; 
    long interesting_info_C; 
} 
node_type; 

node_type node[MAX_NUMBER_OF_NODES]; 

CRITICAL_SECTION node_critsec[MAX_NUMBER_OF_NODES]; 

कार्यक्रम node_critsec [] द्वारा नियंत्रित महत्वपूर्ण अनुभागों में प्रवेश करता है और छोड़ देता है। तो जब मुझे node n के interesting_info_A/B/C को संसाधित करने की आवश्यकता होती है तो मैं उस नोड (node_critsec [n]) का महत्वपूर्ण खंड दर्ज करता हूं, मेरी प्रसंस्करण करता हूं और फिर छोड़ देता हूं। यह कार्यक्रम पेड़ के चारों ओर घूमता है जो माता-पिता और बच्चों के लिंक के बाद जटिल पथों के सभी प्रकार लेता है। कार्यक्रम पेड़ भी उगाएगा, यानी नए नोड्स जोड़ें और तदनुसार अन्य नोड्स के माता-पिता/बच्चों के लिंक को संशोधित करें (पेड़ कभी भी कम नहीं होता है)। मैं कोशिश करता हूं और सुनिश्चित करता हूं कि प्रत्येक थ्रेड केवल डेडलॉक्स के जोखिम से बचने के लिए एक नोड को ताला लगा देता है। लेकिन फिर मुझे एक समस्या है- अगर मैं एक नया नोड जोड़ रहा हूं तो मैं नोड के माता-पिता को लॉक करना चाहूंगा ताकि मैं बच्चों की सूची समायोजित कर सकूं। बिना किसी डेडलॉक्स के काम करने के लिए सभी को प्राप्त करना या एक ही नोड में डेटा को संशोधित करने का प्रयास करने वाले दो थ्रेड एक दुःस्वप्न का थोड़ा सा हो रहा है। क्या कोई मार्गदर्शक सिद्धांत है जिसके बारे में मुझे निम्नलिखित और किस नोड्स को लॉक/अनलॉक करना है, इसके बारे में निम्नलिखित होना चाहिए - या क्या मुझे बस सुपर-स्मार्ट होना चाहिए और घटनाओं के हर क्रमपरिवर्तन को काम करना चाहिए?

+0

क्या आप समझा सकते हैं कि आप डेडलॉक्स का सामना कर रहे हैं? इसका तात्पर्य है कि या तो आपके ग्राफ में (पेड़ नहीं) या ट्रैवर्सल के दौरान आप बच्चे लॉक प्राप्त करने से पहले पैरेंट लॉक नहीं छोड़ रहे हैं, जो सही करने के लिए बहुत आसान होगा। –

+0

जहां तक ​​मैं इसे समझता हूं, कुछ एल्गोरिदम नीचे-नीचे जाते हैं, जबकि अन्य ऊपर-नीचे जाते हैं, और इसी तरह। मुझे लगता है कि उसका मतलब है कि उसे माता-पिता की सूची में जोड़ने से पहले नए नोड को लॉक रखना होगा अन्यथा कोई अन्य धागा नए नोड को चुरा सकता है या घबरा सकता है (असंगत स्थिति: parent_node एक नोड पर सेट है जो इसे सूचीबद्ध नहीं करता है बच्चे के रूप में नोड)। मुझे नहीं पता कि यह डेटा-संरचना इष्टतम है, लेकिन वह इस के साथ सिंक्रनाइज़ेशन की आवश्यकता के संबंध में सही मानता है। – gimpf

+0

@ टायलर मैकहेनरी: मुझे वास्तव में डेडलॉक्स नहीं मिल रहे हैं, हालांकि मेरे पास अतीत में है। जिन बार मैंने उन्हें प्राप्त किया था, वे हमेशा एक ही समय में दो अलग-अलग नोड्स को लॉक करने वाले धागे में से एक थे। मेरी समस्याएं अब उस प्रकार के हैं जहां दो अलग-अलग धागे एक ही नोड्स डेटा को संसाधित कर रहे हैं। – Mick

उत्तर

14

एक साधारण नियम: कई वस्तुओं को लॉक करते समय डेडलॉक से बचने के लिए हमेशा उन्हें हर जगह एक ही क्रम में लॉक करें। तो यदि आपके पास आइटम ए, बी, सी, और डी हैं तो आपको हमेशा उन्हें वर्णित करना चाहिए, कहें, वर्णमाला क्रम और कोई अन्य नहीं। यदि आपने सी को लॉक कर लिया है और निर्णय लेता है कि आपको बी की आवश्यकता है, तो आपको सी को रिलीज़ करना होगा और फिर बी को लॉक करना होगा और सी

पेड़ में, मुझे लगता है कि आप हमेशा ऊपर से नीचे लॉक कर सकते हैं। यदि आपको माता-पिता को लॉक करने की आवश्यकता है तो आवश्यकतानुसार ताले को रिहा कर दोबारा हासिल करें।

ऐसी अन्य योजनाएं भी हैं जो अच्छी तरह से काम करती हैं, लेकिन यह एक सीधा है।

संपादित करें: आप इसके बारे में थोड़ा कुछ पढ़ सकते हैं here

+0

अपने सही मानते हुए, मुझे इसकी आवाज़ पसंद है। अच्छा और सरल – Mick

+1

@ मिक: हाँ - यह योजना डेडलॉक से बचने के लिए सही है। –

+1

मैं इस विचार को दूसरी बार दूंगा कि यह एक सही योजना है। मैं विशेष रूप से शीर्ष पर पेड़ को लॉक करना पसंद करता हूं, और यदि आप नोड के माता-पिता को लॉक करना चाहते हैं तो आप वर्तमान नोड्स लॉक को छोड़ दें, माता-पिता पर जाएं, और जोड़ी को क्रम में लॉक करें। –

1

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

उस तंत्र का उपयोग करने से एकल थ्रेड की आवश्यकता अलग-अलग नोड्स के लिए कई महत्वपूर्ण वर्गों को प्राप्त करने की आवश्यकता को खत्म कर देगी और इस प्रकार प्रक्रिया को सरल बना दिया जाएगा।

+0

दुर्भाग्यवश, पेड़ बढ़ाना बहुत आम है। – Mick

+0

@ मिक: नए नोड्स को माता-पिता में कैसे जोड़ा जाता है? क्या वे विशिष्ट क्रम में जोड़े गए हैं (उदाहरण के लिए, बी-पेड़ शैली)? या क्या एक बच्चे नोड बस मौजूदा लोगों के अंत में जोड़ा गया है (स्थिति संख्या_of_children पर)? –

+0

दुर्भाग्य से मेरे प्रश्न में सरलीकृत कोड की तुलना में तंत्र अधिक जटिल है ... और मुझे आपके प्रश्न का सही उत्तर देने के लिए बहुत सी चीजों को समझाना होगा। लेकिन क्लिंटप का जवाब मेरे सभी मुद्दों को अच्छी तरह से हल कर सकता है। – Mick

1

यह फ़ाइल सिस्टम में नोड लॉकिंग की याद दिलाता है। यदि आप संदर्भ सामग्री की तलाश में हैं, तो आप लिनक्स, बीएसडी, ओपन सोलरिस में वीएफएस परतों को देख सकते हैं .... हालांकि, चेतावनी दी जानी चाहिए कि यह जटिल चीजें हो सकती है, और इसके परिणामस्वरूप संदर्भ के लिए सबसे अच्छा उदाहरण नहीं हो सकता है।

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

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

  2. उन सभी परिचालनों की एक सूची बनाएं जिन्हें आप अपने पेड़ में बनाना चाहते हैं और उन्हें वर्गीकृत करना (पढ़ना, लिखना, अद्यतन करना, स्थानांतरित करना, नामकरण करना, हटाना, ...) और यह पता लगाना चाहिए कि आप किस डिग्री की डिग्री चाहते हैं। जो आपने लिखा है, उससे आपको केवल पढ़ने के लिए ज़रूरी है। क्या आप थ्रेड ए को उन नोड्स को पढ़ने में सक्षम होना चाहते हैं जो थ्रेड बी द्वारा लिखे जाने के लिए लॉक नहीं हैं? मैं अनुभव से बात करता हूं कि इस कदम को छोड़ने से आपको बहुत समय लग सकता है।

उम्मीद है कि इससे मदद मिलती है।

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