2015-12-04 7 views
13

के साथ मेरे पास नक्शा साफ़ करने से पहले जारी किए जाने वाले ऑब्जेक्ट्स के साथ एक नक्शा है। मैं नक्शा पर फिर से प्रयास करने और वस्तुओं को हटाने/रिलीज करने के लिए प्रेरित हूं क्योंकि मैं इसके माध्यम से चलता हूं।गोलांग समेकित मानचित्र पहुंच

यहाँ उदाहरण https://play.golang.org/p/kAtPoUgMsq

के बाद से नक्शा पुनरावृति करने का एकमात्र तरीका रेंज के माध्यम से है एक नकली निर्भर है, कैसे मैं कई उत्पादकों और कई उपभोक्ताओं को सिंक्रनाइज़ हैं?

मैं मानचित्र को लॉक नहीं करना चाहता क्योंकि इससे पुनरावृत्ति के दौरान हटाने/संशोधित कुंजी को असंभव बना दिया जाएगा।

+0

हमें इसके साथ काम करने के लिए अधिक संदर्भ की आवश्यकता है। मानचित्र में क्या है? क्या यह बड़ा है? एक चीज़ को कितनी तेजी से जारी किया जा रहा है? (क्या _is_ रिलीज़िंग?) क्या यह एक आपदा है यदि एक जारी वस्तु का उपयोग किसी अन्य गोरौटाइन द्वारा किया जाता है, और यदि ऐसा है, तो यह निर्धारित करता है कि मानचित्र से कितनी वस्तु निकाली जाती है? आवेदन क्या है और इसकी प्राथमिकताओं क्या हैं (उदा। थ्रूपुट बनाम विलंबता अधिकतम सीमा)? – twotwotwo

उत्तर

4

आप सभी आवश्यकताओं को राज्य नहीं है (उदाहरण के लिए एक से अधिक ऑब्जेक्ट की रिहाई एक साथ भी हो सकता है, आदि) लेकिन सबसे सरल समाधान मैं के बारे में सोच सकते हैं हटा तत्वों से प्रत्येक के लिए तत्वों को हटाने और एक रिलीज goroutine शुरू करने के लिए है:

for key := range keysToRemove { 
    if v, ok := m[k]; ok { 
     delete(m, k) 
     go release(k, v) 
    } 
} 
+0

क्या इस उत्तर में दी गई विधि वास्तव में पर्याप्त है? (1.6 परिवर्तन के बाद Esp?) क्या भाषा विनिर्देश में कोई जगह है जहां इसे साफ़/निश्चित रूप से उत्तर दिया गया है? – BadZen

+0

मानचित्र के ऊपर कोड नमूने में एक सिंगल गोरौटाइन से उपयोग किया जाता है, इसलिए कोई समवर्ती उपयोग नहीं होने पर सिंक्रनाइज़ेशन आवश्यक नहीं है। – kostya

+0

बेशक ओपी मान रहा है कि पुनरावृत्ति के दौरान समवर्ती लेखकों होंगे। वह कहता है: "मैं नक्शा लॉक नहीं पढ़ना चाहता क्योंकि इससे पुनरावृत्ति के दौरान असंभव कुंजी को हटा/संशोधित करना होगा।" सिर्फ इसलिए कि वह नहीं दिखाता/दिखाता है कि लेखकों का यह मतलब नहीं है कि वे शामिल नहीं हैं। – BadZen

2

अद्यतन अगस्त 2017 (golang 1.9)

अब आप sync पैकेज में एक नया Map प्रकार परिशोधित-निरंतर समय भार, दुकानों के साथ एक समवर्ती नक्शा है, और हटा देता है।
मैक के तरीकों को समवर्ती रूप से कॉल करने के लिए एकाधिक goroutines के लिए यह सुरक्षित है।


मूल जवाब नवम्बर 2016

मैं के बाद से नक्शे से हटाने के लिए एक लिखने आपरेशन माना जाता है नक्शा

समझ में आता है कि ताला, पढ़ने के लिए नहीं करना चाहते, और सभी अन्य पढ़ने और लिखने के साथ क्रमबद्ध होना चाहिए। यह हटाने को पूरा करने के लिए एक लिखें लॉक का तात्पर्य है। (स्रोत: this answer)

सबसे खराब स्थिति (कई लेखकों और पाठकों) मान लिया जाये, तो आप orcaman/concurrent-map के कार्यान्वयन है, जो एक Remove() method कई sync.RWMutex का उपयोग कर, क्योंकि ताला बाधाओं से बचने की है पर एक नज़र ले जा सकते हैं, इस समवर्ती नक्शा है कई (SHARD_COUNT) नक्शा shards के लिए डाइव किया गया।
यह केवल एक RWMutexas in this example का उपयोग करने से तेज़ है।

6

कठोर मानचित्र पहुंच के बिना map से चीजों को साफ़ करने के तरीकों का एक समूह है। आपके आवेदन के लिए क्या काम करता है यह इस पर निर्भर करता है कि यह क्या कर रहा है।

0) जब आप उस पर काम करते हैं तो बस मानचित्र को लॉक करें। यदि नक्शा बहुत बड़ा नहीं है, या आपके पास कुछ विलंबता सहनशीलता है, तो यह काम जल्दी से हो जाता है (समय के संदर्भ में आप इस पर खर्च करते हैं) और आप अन्य सामानों के बारे में सोचने के लिए आगे बढ़ सकते हैं। यदि यह बाद में कोई समस्या बन जाती है, तो आप तब समस्या पर वापस आ सकते हैं।

1) ऑब्जेक्ट्स या पॉइंटर्स को लॉक करते समय मानचित्र को साफ़ करें और साफ़ करें, फिर ऑब्जेक्ट को पृष्ठभूमि में छोड़ दें। यदि समस्या यह है कि खुद को रिहा करने की धीमी गति से लॉक को लंबे समय तक रखा जाएगा, तो यह उसके लिए आसान कामकाज है।

2) यदि कुशल पढ़े मूल रूप से सभी महत्वपूर्ण हैं, तो atomic.Value का उपयोग करें। यह आपको एक मानचित्र को एक नए और अलग से पूरी तरह से बदलने देता है।यदि लिखते हैं तो आपके वर्कलोड का अनिवार्य रूप से 0% है, कुशल प्रत्येक परिवर्तन पर एक नया नक्शा बनाने की लागत को संतुलित करता है। यह दुर्लभ है, लेकिन ऐसा होता है, उदाहरण के लिए, encoding/gob इस प्रकार के प्रकारों का एक वैश्विक मानचित्र है।

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

रिलीज और उपयोग के बीच दौड़ का मुद्दा भी है: goroutine ए मानचित्र से कुछ प्राप्त करता है, बी मानचित्र को साफ़ करता है और चीज़ को रिलीज़ करता है, ए रिलीज़ की गई चीज़ का उपयोग करता है।

जब आप इसका उपयोग करते हैं या इसे छोड़ते हैं तो प्रत्येक मान को लॉक करना एक रणनीति है; तो आपको ताले की जरूरत है लेकिन वैश्विक नहीं।

एक और दौड़ के परिणामों को सहन करना है यदि वे ज्ञात हैं और विनाशकारी नहीं हैं; उदाहरण के लिए, net.Conn एस के समवर्ती उपयोग को इसके दस्तावेज़ों द्वारा स्पष्ट रूप से अनुमति दी जाती है, इसलिए इन-उपयोग कनेक्शन को बंद करने से यह त्रुटि पर अनुरोध हो सकता है लेकिन यह अपरिभाषित ऐप व्यवहार का कारण नहीं बनता है। आपको वास्तव में यह सुनिश्चित करना होगा कि आप जानते हैं कि आप क्या प्राप्त कर रहे हैं, हालांकि, many benign-seeming races aren't का कारण बनता है।

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

किसी भी तरह से इन ताले को चैनलों से बदलने की कोशिश करना मोहक हो सकता है लेकिन मुझे इससे कोई लाभ नहीं दिख रहा है। यह अच्छा है जब आप मुख्य रूप से साझा डेटा के बजाय प्रक्रियाओं के बीच संचार के संदर्भ में अपने ऐप को डिज़ाइन कर सकते हैं, लेकिन जब आपने डेटा साझा किया है, तो अन्यथा नाटक करने में कोई उपयोग नहीं है। साझा डेटा तक असुरक्षित पहुंच को छोड़कर यह है कि ताले क्या हैं।