एक सामान्य सी ++ आवरण के साथ रस्ट के स्वामित्व मॉडल को प्राप्त करना संभव है?


15

रस्ट की संगरोध सुरक्षा पर इस लेख के माध्यम से देख रहे हैं:

http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html

मैं सोच रहा था कि C ++ 11 (या नए) में इनमें से कितने विचार प्राप्त किए जा सकते हैं। विशेष रूप से क्या मैं एक स्वामी वर्ग बना सकता हूँ जो स्वामित्व को किसी भी विधि में स्थानांतरित करता है जिससे इसे पारित किया जा सकता है? ऐसा लगता है कि C ++ के पास चर को पारित करने के इतने तरीके हैं कि यह असंभव होगा, लेकिन हो सकता है कि मैं यह सुनिश्चित करने के लिए कक्षा या टेम्पलेट पर कुछ प्रतिबंध लगा सकता हूं कि प्रत्येक विधि पास के साथ कुछ टेम्पलेट कोड निष्पादित हो जाए?


लिंक के कुछ उद्धरण इस प्रश्न को बेहतर बनाएंगे
मार्टिन बा

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

3
आपको नहीं लगता कि आप इस तरह से उधार को व्यक्त कर सकते हैं कि C ++ कंपाइलर सत्यापित कर सकता है, इसलिए आपको संबंधित प्रदर्शन हिट के साथ रनटाइम प्रवर्तन का सहारा लेना होगा।
कोडइन्चोस

1
C ++ 11 में स्मार्ट पॉइंटर्स द्वारा पहले से लागू की गई स्वामित्व की गुंजाइश नहीं है?
अक्षत महाजन

1
@JerryJeremiah जंग में संदर्भ प्रकार की एक विस्तृत विविधता है। मूल वाले, &उपयोग किए जाने के लिए किसी भी प्रकार के प्रचार की आवश्यकता नहीं रखते हैं। यदि आप कुछ &mutसमय के लिए प्रयास करते हैं, तब भी आपको एक ही आइटम में एक और संदर्भ (परस्पर या नहीं) मिला है, तो आप संकलन नहीं कर पाएंगे। RefCell<T>चाल की जांच समय से चलाने के लिए है, तो आप एक आतंक अगर तुम करने की कोशिश मिल जाएगा .borrow_mut()कुछ पहले से ही एक सक्रिय है .borrow()या .borrow_mut()। जंग के पास Rc<T>(साझा स्वामित्व सूचक) और उसके सहोदर भी हैं Weak<T>, लेकिन वे स्वामित्व के बारे में हैं, पारस्परिकता के बारे में नहीं। एक छड़ी RefCell<T>अस्थिरता के लिए उन्हें अंदर।
8bittree

जवाबों:


8

C ++ में किसी फ़ंक्शन में पैरामीटर पास करने के तीन तरीके हैं: मूल्य द्वारा, लैवल्यू संदर्भ द्वारा, और रेवल्यू संदर्भ द्वारा। इनमें से, मूल्य से गुजरना इस अर्थ में स्वामित्व बनाता है कि कहा गया फ़ंक्शन अपनी प्रति प्राप्त करता है, और प्रतिद्वंद्विता संदर्भ से गुजरना इंगित करता है कि मूल्य का उपभोग किया जा सकता है, अर्थात अब कॉलर द्वारा उपयोग नहीं किया जाएगा। लैवल्यू रेफरेंस से गुजरने का मतलब है कि ऑब्जेक्ट को कॉलर से अस्थायी रूप से उधार लिया गया है।

हालाँकि, ये "कन्वेंशन द्वारा" होते हैं और हमेशा कंपाइलर द्वारा जांचे नहीं जा सकते। और आप गलती से एक लैवल्यू संदर्भ को एक रवैल्यू संदर्भ में बदल सकते हैं std::move()। लगातार, तीन समस्याएं हैं:

  • एक संदर्भ वस्तु को संदर्भित कर सकता है। रस्ट का जीवनकाल प्रणाली इसे रोकता है।

  • किसी भी समय एक से अधिक परस्पर / गैर-कॉन्स्टेबल संदर्भ सक्रिय हो सकते हैं। रस्ट का उधार चेकर इसे रोकता है।

  • आप संदर्भों से बाहर नहीं निकल सकते। आप एक कॉल साइट पर नहीं देख सकते हैं कि क्या यह फ़ंक्शन आपके फ़ंक्शन के लिए एक संदर्भ बनाता है, जिसे बिना किसी फ़ंक्शन के हस्ताक्षर के बिना जाना जाता है। इसलिए आप न तो संदर्भों को रोक सकते हैं, न ही अपनी कक्षाओं के किसी विशेष तरीके को हटाकर और न ही कुछ "नो रेफरेंस" स्टाइल गाइड के अनुपालन के लिए कॉल साइट का ऑडिट करके।

जीवनकाल की समस्या बुनियादी स्मृति सुरक्षा के बारे में है। जब संदर्भित ऑब्जेक्ट की समय सीमा समाप्त हो गई है तो संदर्भ का उपयोग करना अवैध है। लेकिन जीवनकाल के बारे में भूलना बहुत आसान है जब आप किसी वस्तु के भीतर एक संदर्भ संग्रहीत करते हैं, विशेष रूप से जब वह वस्तु वर्तमान गुंजाइश को रेखांकित करती है। C ++ टाइप सिस्टम इसके लिए जिम्मेदार नहीं हो सकता क्योंकि यह ऑब्जेक्ट लाइफटाइम को बिल्कुल भी मॉडल नहीं करता है।

std::weak_ptrस्मार्ट सूचक एक सादे संदर्भ के लिए इसी तरह एनकोड स्वामित्व अर्थ विज्ञान करता है, लेकिन जरूरी है कि संदर्भित वस्तु एक के माध्यम से किया जाता है shared_ptr, यानी संदर्भ बार गणना है। यह एक शून्य लागत अमूर्तता नहीं है।

हालांकि C ++ में एक कास्ट सिस्टम है, यह ट्रैक नहीं करता है कि किसी ऑब्जेक्ट को संशोधित किया जा सकता है, लेकिन यह ट्रैक करता है कि किसी ऑब्जेक्ट को उस विशेष संदर्भ के माध्यम से संशोधित किया जा सकता है या नहीं । "निडर संगति" के लिए पर्याप्त गारंटी प्रदान नहीं करता है। इसके विपरीत, रस्ट गारंटी देता है कि यदि कोई सक्रिय परिवर्तनशील संदर्भ है जो केवल संदर्भ है ("मैं केवल एक ही हूं जो इस ऑब्जेक्ट को बदल सकता है") और यदि गैर-परस्पर संदर्भ हैं तो ऑब्जेक्ट के सभी संदर्भ गैर-परस्पर हैं ("जब मैं ऑब्जेक्ट से पढ़ सकता हूं, तो कोई भी इसे बदल नहीं सकता है")।

C ++ में आपको किसी म्यूटेक्स के साथ स्मार्ट पॉइंटर के माध्यम से किसी ऑब्जेक्ट तक पहरा देने का प्रलोभन दिया जा सकता है। लेकिन जैसा कि ऊपर एक बार चर्चा की जा चुकी है कि हम इसके अपेक्षित जीवनकाल से बच सकते हैं। इसलिए ऐसा स्मार्ट पॉइंटर गारंटी नहीं दे सकता है कि यह अपने प्रबंधित ऑब्जेक्ट तक पहुंच का एकल बिंदु है। इस तरह की योजना वास्तव में व्यवहार में काम कर सकती है क्योंकि अधिकांश प्रोग्रामर खुद को तोड़फोड़ नहीं करना चाहते हैं, लेकिन एक प्रकार-प्रणाली के दृष्टिकोण से यह अभी भी पूरी तरह से निराधार नहीं है।

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

बेशक कई मामलों में C ++ और Rust एक जैसे होते हैं, विशेषकर सांख्यिकीय रूप से निर्धारित वस्तु जीवन काल की उनकी अवधारणाओं के बारे में। लेकिन जब तक सही सी ++ प्रोग्राम लिखना संभव है (बशर्ते कि कोई भी प्रोग्रामर कोई गलती नहीं करता है), रुस्ट चर्चा की गई संपत्तियों के बारे में शुद्धता की गारंटी देता है


यदि समस्या यह है कि C ++ मूल भाषा में स्वामित्व को ट्रैक नहीं करता है, तो क्या मेटा-प्रोग्रामिंग के माध्यम से उस कार्यक्षमता को लागू करना संभव होगा? इसका मतलब है कि आप एक नया स्मार्ट पॉइंटर क्लास बनाएंगे, जो मेमोरी (1) द्वारा सुरक्षित होगा, यह उन वस्तुओं के लिए विशेष रूप से इंगित करने के लिए है जो केवल एक ही क्लास से स्मार्ट पॉइंटर्स का उपयोग करते हैं और (2) टेम्प्लेट के माध्यम से ट्रैकिंग स्वामित्व
इलियट गोरोखोवस्की

2
@ElliotGorokhovsky नहीं, क्योंकि टेम्प्लेट कोर भाषा की विशेषताओं जैसे संदर्भों को अक्षम नहीं कर सकता है। एक स्मार्ट पॉइंटर एक संदर्भ प्राप्त करना अधिक कठिन बना सकता है, लेकिन उस बिंदु पर आप भाषा से लड़ रहे हैं - अधिकांश मानक पुस्तकालय कार्यों को संदर्भ की आवश्यकता होती है। किसी संदर्भ के जीवनकाल को टेम्प्लेट के माध्यम से जांचना भी संभव नहीं है क्योंकि भाषा जीवन भर की कोई भी अवधारणा प्रस्तुत नहीं करती है।
अमन

मैं देखता हूं, धन्यवाद
इलियट गोरोखोवस्की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.