जवाबों:
मैं अपनी खुद की व्याख्या लिखने जा रहा था, लेकिन इस विकिपीडिया लेख ने इसे बहुत ज्यादा बढ़ा दिया।
यहाँ मूल अवधारणा है:
कॉपी-ऑन-राइट (कभी-कभी "गाय" के रूप में संदर्भित) कंप्यूटर प्रोग्रामिंग में उपयोग की जाने वाली एक अनुकूलन रणनीति है। मौलिक विचार यह है कि यदि एकाधिक कॉलर्स संसाधनों के लिए पूछते हैं जो शुरू में अप्रभेद्य हैं, तो आप उन्हें एक ही संसाधन के लिए संकेत दे सकते हैं। यह फ़ंक्शन तब तक बनाए रखा जा सकता है जब तक कि कोई कॉलर संसाधन की अपनी "प्रतिलिपि" को संशोधित करने का प्रयास नहीं करता है, जिस बिंदु पर हर किसी को दिखाई देने वाले परिवर्तनों को रोकने के लिए एक सच्ची निजी प्रतिलिपि बनाई जाती है। यह सब पारदर्शी रूप से कॉल करने वालों के लिए होता है। प्राथमिक लाभ यह है कि यदि कोई कॉलर कभी कोई संशोधन नहीं करता है, तो किसी भी निजी प्रतिलिपि की आवश्यकता कभी नहीं होती है।
यहाँ भी गाय के सामान्य उपयोग का एक आवेदन है:
गाय की अवधारणा को Microsoft SQL Server 2005 जैसे डेटाबेस सर्वर पर तत्काल स्नैपशॉट के रखरखाव में भी उपयोग किया जाता है। त्वरित स्नैपशॉट डेटा को अद्यतन करते समय डेटा की पूर्व-संशोधन प्रतिलिपि संग्रहीत करके डेटाबेस के स्थिर दृश्य को संरक्षित करते हैं। इंस्टेंट स्नैपशॉट का उपयोग परीक्षण उपयोग या पल-निर्भर रिपोर्ट के लिए किया जाता है और बैकअप को बदलने के लिए उपयोग नहीं किया जाना चाहिए।
clone()
लागू करने के लिए उपयोग करता है fork()
- माता-पिता की प्रक्रिया की स्मृति बच्चे के लिए होती है।
"राइट ऑन राइट" का अर्थ कम या ज्यादा होता है, जो ऐसा लगता है: सभी के पास एक ही डेटा की एक साझा की गई कॉपी है, जब तक कि यह लिखा नहीं जाता है , और फिर एक प्रतिलिपि बनाई जाती है। आमतौर पर समसामयिक समस्याओं के समाधान के लिए कॉपी-ऑन-राइट का उपयोग किया जाता है। में ZFS , उदाहरण के लिए, डिस्क पर डेटा ब्लॉक कॉपी-ऑन-राइट आवंटित किए जाते हैं; जब तक कोई परिवर्तन नहीं होता है, आप मूल ब्लॉक रखते हैं; एक परिवर्तन ने केवल प्रभावित ब्लॉकों को बदल दिया। इसका मतलब है कि नए ब्लॉक की न्यूनतम संख्या आवंटित की गई है।
इन परिवर्तनों को आमतौर पर लेनदेन के लिए लागू किया जाता है , अर्थात, उनके पास ACID होता है गुण होते हैं। यह कुछ समसामयिक मुद्दों को समाप्त करता है, क्योंकि तब आपको गारंटी दी जाती है कि सभी अपडेट परमाणु हैं।
A
। प्रक्रिया 1
, 2
, 3
, 4
प्रत्येक अभाव इसकी एक प्रति बनाने के लिए और "लिखने पर कॉपी" प्रणाली कुछ भी नहीं की नकल की है अभी तक सब कुछ अभी भी पढ़ रही है इसे पढ़ने, एक में शुरू करने के लिए A
। अब प्रक्रिया 3
इसकी प्रतिलिपि बनाने के लिए एक बदलाव करना चाहती है A
, प्रक्रिया 3
अब वास्तव में प्रतिलिपि A
बनाएगी और डेटा का एक नया ब्लॉक बनाएगी जिसे कहा जाता है B
। प्रक्रिया 1
, 2
, 4
अभी भी ब्लॉक पढ़ रहे हैं A
प्रक्रिया 3
अभी पढ़ रहा है B
।
A
एक नई प्रतिलिपि बनाने वाली होनी चाहिए, वह परिवर्तन कर रही है। यदि आप पूछ रहे हैं कि क्या होता है अगर एक पूरी तरह से नई प्रक्रिया साथ आती है और बदलती है, A
तो मेरा स्पष्टीकरण वास्तव में उसके लिए पर्याप्त विवरण में नहीं जाता है। यह विशिष्ट कार्यान्वयन होगा और आपको इस बारे में ज्ञान की आवश्यकता होगी कि आप बाकी के काम कैसे करना चाहते हैं, जैसे फ़ाइल \ डाटा लॉकिंग, आदि
मैं कॉपी-ऑन-राइट पर समान उत्तर नहीं दूंगा। मुझे लगता है कि एंड्रयू का जवाब और चार्ली का जवाब पहले ही बहुत स्पष्ट कर चुका है। मैं आपको ओएस दुनिया से एक उदाहरण दूंगा, बस यह उल्लेख करने के लिए कि इस अवधारणा का व्यापक रूप से उपयोग कैसे किया जाता है।
हम एक नई प्रक्रिया का उपयोग fork()
या vfork()
निर्माण कर सकते हैं । vfork कॉपी-ऑन-राइट की अवधारणा का अनुसरण करता है। उदाहरण के लिए, vfork द्वारा बनाई गई चाइल्ड प्रोसेस डेटा और कोड सेगमेंट को पेरेंट प्रोसेस के साथ साझा करेगी। यह फोर्किंग टाइम को तेज करता है। यदि आप vfork द्वारा निष्पादित निष्पादन कर रहे हैं तो vfork का उपयोग करना अपेक्षित है। तो vfork चाइल्ड प्रोसेस बनाएगा जो डेटा और कोड सेगमेंट को उसके अभिभावक के साथ साझा करेगा लेकिन जब हम निष्पादन को कॉल करेंगे, तो यह चाइल्ड प्रोसेस के एड्रेस स्पेस में एक नई निष्पादन योग्य की छवि को लोड करेगा।
vfork
गाय का उपयोग नहीं करता है। वास्तव में यदि बच्चा कुछ लिखता है, तो इसका परिणाम अपरिभाषित व्यवहार हो सकता है और पृष्ठों की नकल नहीं !! वास्तव में, आप कह सकते हैं कि दूसरा तरीका कुछ हद तक सही है। गाय की तरह काम करता है vfork
जब तक कि साझा स्थान में कुछ संशोधित नहीं होता है!
बस एक और उदाहरण प्रदान करने के लिए, मर्क्यूरियल कॉपी-ऑन-राइट का उपयोग करता है स्थानीय रिपॉजिटरी को वास्तव में "सस्ता" ऑपरेशन बनाने के लिए का उपयोग किया है।
सिद्धांत अन्य उदाहरणों के समान है, सिवाय इसके कि आप मेमोरी में ऑब्जेक्ट्स के बजाय भौतिक फ़ाइलों के बारे में बात कर रहे हैं। प्रारंभ में, एक क्लोन डुप्लिकेट नहीं है, लेकिन मूल के लिए एक कड़ी है । जब आप क्लोन में फ़ाइलों को बदलते हैं, तो नए संस्करण का प्रतिनिधित्व करने के लिए प्रतियां लिखी जाती हैं।
मुझे PHP में zval के बारे में यह अच्छा लेख मिला , जिसमें गाय का भी उल्लेख किया गया है:
कॉपी ऑन राइट (संक्षिप्त रूप में 'गाय') एक ट्रिक है जो मेमोरी को बचाने के लिए डिज़ाइन की गई है। इसका उपयोग आमतौर पर सॉफ्टवेयर इंजीनियरिंग में अधिक किया जाता है। इसका मतलब है कि जब आप पहले से ही एक ज़वल को इंगित कर रहे थे, तो PHP मेमोरी को कॉपी करेगा (या नए मेमोरी क्षेत्र को आवंटित करेगा)।
एक अच्छा उदाहरण Git है, जो blobs को स्टोर करने की रणनीति का उपयोग करता है। यह हैश का उपयोग क्यों करता है? आंशिक रूप से क्योंकि ये प्रदर्शन करने में आसान होते हैं, लेकिन यह भी आसान है क्योंकि यह एक गाय रणनीति का अनुकूलन करने के लिए सरल बनाता है। जब आप कुछ फ़ाइलों के साथ एक नया कमिट करते हैं, तो अधिकांश वस्तुएं बदल जाती हैं और पेड़ नहीं बदलेंगे। इसलिए प्रतिबद्ध, हैश से बने विभिन्न बिंदुओं के माध्यम से वस्तु का एक गुच्छा संदर्भित करेगा जो पहले से मौजूद है, जिससे पूरे इतिहास को स्टोर करने के लिए आवश्यक भंडारण स्थान बहुत छोटा हो जाता है।
इसके बाद डेकोरेटर डिजाइन पैटर्न का उपयोग करके एक कॉपी-ऑन-राइट (गाय) पायथन कार्यान्वयन है । एक अपरिवर्तनीय Value
वस्तु का संदर्भ एक उत्परिवर्तित CowValue
वस्तु (डेकोरेटर) द्वारा रखा जाता है । CowValue
वस्तु आगे सब अपरिवर्तनीय करने के लिए अनुरोध को पढ़ने Value
के लिए एक नया अपरिवर्तनीय बनाकर वस्तु और अवरोध सब लिखने अनुरोध Value
सही राज्य के साथ वस्तु। CowValue
वस्तु उथले चर के बीच प्रतिलिपि बनाई जानी चाहिए के आदान-प्रदान की अनुमति के लिए Value
वस्तु।
import abc
import copy
class BaseValue(abc.ABC):
@abc.abstractmethod
def read(self):
raise NotImplementedError
@abc.abstractmethod
def write(self, data):
raise NotImplementedError
class Value(BaseValue):
def __init__(self, data):
self.data = data
def read(self):
return self.data
def write(self, data):
pass
class CowValue(BaseValue):
def __init__(self, data):
self.value = Value(data)
def read(self):
return self.value.read()
def write(self, data):
self.value = Value(data)
v = CowValue(1)
w = copy.copy(v) # shares the immutable Value object
assert v.read() == w.read()
assert id(v.value) == id(w.value)
w.write(2) # creates a new immutable Value object with the correct state
assert v.read() != w.read()
assert id(v.value) != id(w.value)