2014-05-17 24 views
5

गो में दौड़ की स्थिति को रोकने के लिए कुछ अच्छे अभ्यास क्या हैं?गोलांग: दौड़ की स्थिति से परहेज

केवल एक जिसे मैं सोच सकता हूं वह गोरोटाइन्स के बीच डेटा साझा नहीं कर रहा है - माता-पिता गोरौटाइन ऑब्जेक्ट की बजाए ऑब्जेक्ट की गहरी प्रति भेजता है, इसलिए बच्चे गोरौटाइन कुछ ऐसा नहीं कर सकता जो माता-पिता कर सकता है। यह अधिक ढेर मेमोरी का उपयोग करेगा, लेकिन दूसरा विकल्प हैस्केल सीखना है: पी

संपादित करें: क्या, क्या कोई परिदृश्य है जिसमें ऊपर वर्णित विधि अभी भी दौड़ की स्थिति में चल सकती है?

+1

रेस की स्थिति डीबग करना मुश्किल है, उन्हें टालना भी मुश्किल है। मैं रॉब पाइक http://vimeo.com/49718712 द्वारा वर्णित पैटर्न के बारे में सोचने का सुझाव दूंगा क्योंकि वह कुछ संरचनाओं के माध्यम से जाता है कि कैसे चैनल और सीएसपी अर्थशास्त्र म्यूटक्स से जुड़े सभी मुद्दों के बारे में चिंतित होने के बजाय डिज़ाइन द्वारा सुरक्षित एप्लिकेशन बनाते हैं। मुझे खेद है कि यह आपके प्रश्न का उत्तर नहीं देता है, लेकिन मुझे आशा है कि यह नए विचारों के लिए और अधिक दरवाजे खुलता है। – ymg

+0

लिंक के लिए धन्यवाद। हां, दौड़ की स्थिति को रोकने के लिए मुश्किल है, लेकिन डीबग करने के लिए भी मुश्किल है! मुझे लगता है कि संग्रह का एक अपरिवर्तनीय संस्करण कुछ हद तक समस्या को कम करेगा, लेकिन फिर हम कार्यात्मक प्रोग्रामिंग के पिछवाड़े में वापस आ गए हैं। – tldr

+0

वहाँ _are_ अन्य अपरिवर्तनीय-आधारित/कार्यात्मक भाषाओं (जैसे कि एफ #), लेकिन यह वास्तव में शैली के बारे में है। आप अधिक स्मृति की आवश्यकता के बारे में सही हैं, लेकिन उचित डिजाइन कुछ ओवरहेड को खत्म कर सकता है। उदाहरण के लिए, एक भद्दा '2n' की बजाय औसत पर 'एन लॉग एन' स्पेस (या कुछ संभावित मामलों के लिए कम) में लिखने पर संशोधनों के सरणी किए जा सकते हैं। यद्यपि भाषा/अनुकूलक समर्थन प्रयोजन-निर्मित भाषाओं के लिए कुछ पागल चीजें कर सकता है ... –

उत्तर

13

दौड़ की स्थिति निश्चित रूप से अभी भी बिना डेटा डेटा संरचनाओं के साथ मौजूद हो सकती है। पर विचार करें निम्नलिखित:

B asks A for the currentCount 
C asks A for the currentCount 
B sends A (newDataB, currentCount + 1) 
A stores newDataB at location currentCount+1 
C sends A (newDataC, currentCount + 1) 
A stores newDataC at currentCount + 1 (overwriting newDataB; race condition) 

इस रेस स्थिति और एक में निजी परिवर्तनशील राज्य है, लेकिन कोई परिवर्तनशील साझी डाटा संरचनाओं की आवश्यकता भी बी या सी में परिवर्तनशील राज्य कुछ भी बी या सी को रोकने के लिए क्या कर सकते हैं की आवश्यकता नहीं है अनुबंध की समझ के बिना इस दौड़ की स्थिति एक प्रस्ताव प्रदान करता है।

यहां तक ​​कि जैसे ही राज्य समीकरण में प्रवेश करता है, तब भी हास्केल इस तरह की दौड़ की स्थिति का सामना कर सकता है, और राज्य को वास्तविक प्रणाली से पूरी तरह से खत्म करना बहुत मुश्किल है। आखिरकार आप अपने कार्यक्रम को वास्तविकता के साथ बातचीत करना चाहते हैं, और वास्तविकता राज्यपूर्ण है।विकिपीडिया एसटीएम का उपयोग कर a helpful race condition example in Haskell देता है।

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

लेकिन आखिरकार, गो कॉन्सुरेंसी पर सी के इतिहास का पालन करता है: आप अपने कोड के लिए कुछ स्वामित्व नियम बनाते हैं (जैसे @ tux21b ऑफ़र) और सुनिश्चित करें कि आप हमेशा उनका अनुसरण करें, और यदि आप इसे पूरी तरह से करेंगे सभी महान काम करते हैं, और यदि आप कभी गलती करते हैं, तो जाहिर है कि यह आपकी गलती है, न कि भाषा।

(मुझे गलत मत, मैं जाओ पसंद है, काफी एक बहुत वास्तव में और यह कुछ अच्छा उपकरण संगामिति आसान बनाने के लिए प्रदान करता है यह सिर्फ कई भाषा उपकरण प्रदान नहीं करता है मदद करने के लिए संगामिति सही बनाने कि।।। आप ने कहा। tux21b का जवाब बहुत अच्छी सलाह प्रदान करता है, और रेस डिटेक्टर निश्चित रूप से दौड़ की स्थिति को कम करने के लिए एक शक्तिशाली उपकरण है। यह सिर्फ भाषा का हिस्सा नहीं है, और यह परीक्षण के बारे में है, सहीता नहीं; वे नहीं हैं एक ही बात)

संपादित करें:। एक अनुबंध जहां कई दलों में एक ही Dat में परिवर्तन नहीं करते बनाने: के बारे में क्यों अपरिवर्तनीय डेटा संरचनाओं चीजों को आसान बनाने सवाल करने के लिए, यह अपने प्रारंभिक बिंदु के विस्तार है संरचना। यदि डेटा संरचना अपरिवर्तनीय है, तो यह मुफ्त में आता है ...

कई भाषाओं में अपरिवर्तनीय संग्रह और कक्षाओं का एक समृद्ध सेट है। सी ++ आपको कुछ भी के बारे में const देता है। उद्देश्य-सी में उत्परिवर्तनीय उप-वर्गों के साथ अपरिवर्तनीय संग्रह हैं (जो const से पैटर्न का एक अलग सेट बनाता है)। स्कैला में कई संग्रह प्रकारों के अलग-अलग परिवर्तनीय और अपरिवर्तनीय संस्करण हैं, और यह अपरिवर्तनीय संस्करणों का उपयोग करने के लिए सामान्य अभ्यास है। एक विधि हस्ताक्षर में अपरिवर्तनीयता घोषित करना अनुबंध का एक महत्वपूर्ण संकेत है।

जब आप []byte को गोरौटाइन में पास करते हैं, तो कोड से यह जानने का कोई तरीका नहीं है कि गोरौटाइन स्लाइस को संशोधित करने का इरादा रखता है, न ही जब आप स्लाइस को संशोधित कर सकते हैं। वहां एक पैटर्न उभर रहा है, लेकिन वे सैमसंगिक्स को स्थानांतरित करने से पहले सी ++ ऑब्जेक्ट स्वामित्व की तरह हैं; बहुत अच्छे दृष्टिकोण, लेकिन यह जानने का कोई तरीका नहीं है कि कौन सा उपयोग में है। यह एक महत्वपूर्ण बात है कि प्रत्येक कार्यक्रम को सही तरीके से करने की ज़रूरत है, फिर भी भाषा आपको कोई अच्छा उपकरण नहीं देती है, और डेवलपर्स द्वारा उपयोग किए जाने वाले कोई सार्वभौमिक पैटर्न नहीं है।

+1

यह एक उत्कृष्ट उत्तर है। क्या आप इस बात पर विस्तार कर सकते हैं कि अपरिवर्तनीय डेटा संरचनाएं चीजों को कैसे आसान बनाती हैं? – tldr

6

गो स्मृति सुरक्षा को स्थिर रूप से लागू नहीं करता है। बड़े कोड अड्डों में भी समस्या को संभालने के कई तरीके हैं, लेकिन उनमें से सभी को आपका ध्यान देने की आवश्यकता है।

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

  • यदि आपका डेटा कई उपयोगकर्ताओं द्वारा साझा किया जाता है और अक्सर यह नहीं बदलता है, तो आप वैश्विक स्तर पर उस डेटा पर एक पॉइंटर साझा कर सकते हैं और सभी को इसे पढ़ने की अनुमति दे सकते हैं। यदि कोई गोरौटाइन इसे बदलना चाहता है, तो उसे कॉपी-ऑन-राइट मुहावरे का पालन करने की आवश्यकता है, यानी ऑब्जेक्ट की प्रतिलिपि बनाएँ, डेटा को म्यूट करें, पॉइंटर को नई वस्तु पर सेट करने की कोशिश करें जैसे कि atomic.CompareAndSwap।

  • एक म्यूटेक्स का उपयोग करना (या एक RWMutex यदि आप कई समवर्ती पाठकों को एक बार में अनुमति देना चाहते हैं) यह बुरा नहीं है। निश्चित रूप से, एक म्यूटेक्स कोई रजत बुलेट नहीं है और यह अक्सर सिंक्रनाइज़ेशन करने के लिए एक अच्छा फिट नहीं होता है (और कई भाषाओं में इसका उपयोग अत्यधिक खराब होता है), लेकिन कभी-कभी यह सबसे सरल और सबसे कुशल समाधान होता है।

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

गो टूल भी बहुत मूल्यवान race detector के साथ आता है, जो रनटाइम पर दौड़ का पता लगाने में सक्षम है। बहुत से परीक्षण लिखें और रेस डिटेक्टर सक्षम के साथ उन्हें निष्पादित करें और प्रत्येक त्रुटि संदेश को गंभीरता से लें। वे आमतौर पर एक खराब या जटिल डिजाइन इंगित करते हैं।

(पुनश्च:। तुम्हें पता है, Rust पर एक नज़र लेने के लिए अगर आप एक संकलक और प्रकार प्रणाली है कि संकलन समय के दौरान समवर्ती पहुँच सत्यापित करने में सक्षम है चाहते हैं, जबकि अभी भी साझा राज्य की इजाजत दी मैं इसे अपने आप उपयोग नहीं किया है चाहते हो सकता है, लेकिन विचार काफी आशाजनक दिखते हैं।)

+0

ये सभी मान्य अंक हैं, और यदि वे पूरे कोड को लिख रहे थे तो वे काम करेंगे। लेकिन, अगर मेरा गोरौटाइन बाहरी पुस्तकालय से एक फ़ंक्शन चला रहा है, तो मुझे यह सुनिश्चित करने के लिए इसके कार्यान्वयन के माध्यम से जाना होगा कि लाइब्रेरी का डेवलपर अनुबंध द्वारा भी पालन कर रहा है।मुझे लगता है कि किसी भी राज्य को साझा नहीं करना किसी भी बाहरीता से खुद को अपनाना आसान बनाता है। क्या कोई परिदृश्य है जहां मेरा प्रस्तावित समाधान अभी भी दौड़ की स्थिति में चला सकता है? – tldr

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