लॉक (कंप्यूटर साइंस): Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
{{Short description|Synchronization mechanism for enforcing limits on access to a resource}} | {{Short description|Synchronization mechanism for enforcing limits on access to a resource}} | ||
[[कंप्यूटर विज्ञान]] में, एक '''लॉक''' या म्युटेक्स (पारस्परिक बहिष्कार से) एक [[तुल्यकालन आदिम]] है: एक तंत्र जो निष्पादन के कई धागे होने पर संसाधन तक पहुंच पर सीमाएं लागू करता है। एक पारस्परिक बहिष्करण समवर्ती नियंत्रण नीति को लागू करने के लिए एक ताला बनाया गया है, और विभिन्न संभावित विधियों के साथ विभिन्न अनुप्रयोगों के लिए कई अद्वितीय कार्यान्वयन उपस्तिथ है। | [[कंप्यूटर विज्ञान]] में, एक '''लॉक''' या म्युटेक्स (पारस्परिक बहिष्कार से) एक [[तुल्यकालन आदिम]] है: एक तंत्र जो निष्पादन के कई धागे होने पर संसाधन तक पहुंच पर सीमाएं लागू करता है। एक पारस्परिक बहिष्करण समवर्ती नियंत्रण नीति को लागू करने के लिए एक ताला बनाया गया है, और विभिन्न संभावित विधियों के साथ विभिन्न अनुप्रयोगों के लिए कई अद्वितीय कार्यान्वयन उपस्तिथ है। \\ | ||
== प्रकार == | == प्रकार == | ||
Line 14: | Line 14: | ||
एक [[परमाणु संचालन]] की आवश्यकता का कारण समवर्तीता है, जहां एक से अधिक कार्य एक ही तर्क को निष्पादित करते है। उदाहरण के लिए, निम्नलिखित [[सी (प्रोग्रामिंग भाषा)]] कोड पर विचार करें: | एक [[परमाणु संचालन]] की आवश्यकता का कारण समवर्तीता है, जहां एक से अधिक कार्य एक ही तर्क को निष्पादित करते है। उदाहरण के लिए, निम्नलिखित [[सी (प्रोग्रामिंग भाषा)]] कोड पर विचार करें: | ||
if (lock == 0) { | |||
// lock free, set it | |||
lock = myPID; | |||
} | } | ||
उपरोक्त उदाहरण इस बात की गारंटी नहीं देता है कि कार्य में लॉक है, क्योंकि एक ही समय में एक से अधिक कार्य लॉक का परीक्षण कर सकते है। चूंकि दोनों कार्य यह पता लगाएंगे कि लॉक मुक्त है, दोनों कार्य लॉक को सेट करने का प्रयास करेंगे, बिना यह जाने कि अन्य कार्य भी लॉक सेट कर रहे है। यदि परमाणु लॉकिंग ऑपरेशन उपलब्ध नहीं है तो डेकर या पीटरसन का एल्गोरिदम संभव विकल्प है। | उपरोक्त उदाहरण इस बात की गारंटी नहीं देता है कि कार्य में लॉक है, क्योंकि एक ही समय में एक से अधिक कार्य लॉक का परीक्षण कर सकते है। चूंकि दोनों कार्य यह पता लगाएंगे कि लॉक मुक्त है, दोनों कार्य लॉक को सेट करने का प्रयास करेंगे, बिना यह जाने कि अन्य कार्य भी लॉक सेट कर रहे है। यदि परमाणु लॉकिंग ऑपरेशन उपलब्ध नहीं है तो डेकर या पीटरसन का एल्गोरिदम संभव विकल्प है। | ||
Line 23: | Line 23: | ||
कुछ भाषाएँ सिंटैक्टिक रूप से तालों का समर्थन करती है। सी शार्प में एक उदाहरण इस प्रकार है: | कुछ भाषाएँ सिंटैक्टिक रूप से तालों का समर्थन करती है। सी शार्प में एक उदाहरण इस प्रकार है: | ||
public class Account // This is a monitor of an account | |||
{ | { | ||
private decimal _balance = 0; | |||
private object _balanceLock = new object(); | |||
public void Deposit(decimal amount) | |||
{ | |||
// Only one thread at a time may execute this statement. | |||
lock (_balanceLock) | |||
{ | |||
_balance += amount; | |||
} | |||
} | |||
public void Withdraw(decimal amount) | |||
{ | |||
// Only one thread at a time may execute this statement. | |||
lock (_balanceLock) | |||
{ | |||
_balance -= amount; | |||
} | |||
} | |||
} | } | ||
Line 67: | Line 67: | ||
</ref> | </ref> | ||
[MethodImpl(MethodImplOptions.Synchronized)] | [MethodImpl(MethodImplOptions.Synchronized)] | ||
public void SomeMethod() | |||
{ | { | ||
// do stuff | |||
} | } | ||
== ग्रैन्युलैरिटी == | == ग्रैन्युलैरिटी == | ||
Line 118: | Line 118: | ||
लॉक-आधारित प्रोग्रामिंग की सबसे बड़ी समस्याओं में से एक यह है कि "ताले रचना नहीं करते है": मॉड्यूल को संशोधित किए बिना या कम से कम उनके आंतरिक के बारे में जाने बिना छोटे, सही लॉक-आधारित मॉड्यूल को समान रूप से सही बड़े प्रोग्राम में जोड़ना कठिनाई है। [[साइमन पीटन जोन्स]] ([[सॉफ्टवेयर लेनदेन स्मृति]] के एक वकील) एक बैंकिंग एप्लिकेशन का निम्नलिखित उदाहरण देते है:<ref>{{Cite encyclopedia |title=Beautiful concurrency |first=Simon |last=Peyton Jones |encyclopedia=Beautiful Code: Leading Programmers Explain How They Think |editor1-first=Greg |editor1-last=Wilson |editor2-first=Andy |editor2-last=Oram |publisher=O'Reilly |year=2007 |url=http://research.microsoft.com/en-us/um/people/simonpj/papers/stm/beautiful.pdf}}</ref> एक वर्ग खाता डिजाइन करें जो कई समवर्ती ग्राहकों को एक खाते में पैसे जमा करने या निकालने की अनुमति देता है, और एक खाते से दूसरे खाते में पैसे ट्रांसफर करने के लिए एक एल्गोरिथम दें। समस्या के पहले भाग का लॉक-आधारित समाधान है: | लॉक-आधारित प्रोग्रामिंग की सबसे बड़ी समस्याओं में से एक यह है कि "ताले रचना नहीं करते है": मॉड्यूल को संशोधित किए बिना या कम से कम उनके आंतरिक के बारे में जाने बिना छोटे, सही लॉक-आधारित मॉड्यूल को समान रूप से सही बड़े प्रोग्राम में जोड़ना कठिनाई है। [[साइमन पीटन जोन्स]] ([[सॉफ्टवेयर लेनदेन स्मृति]] के एक वकील) एक बैंकिंग एप्लिकेशन का निम्नलिखित उदाहरण देते है:<ref>{{Cite encyclopedia |title=Beautiful concurrency |first=Simon |last=Peyton Jones |encyclopedia=Beautiful Code: Leading Programmers Explain How They Think |editor1-first=Greg |editor1-last=Wilson |editor2-first=Andy |editor2-last=Oram |publisher=O'Reilly |year=2007 |url=http://research.microsoft.com/en-us/um/people/simonpj/papers/stm/beautiful.pdf}}</ref> एक वर्ग खाता डिजाइन करें जो कई समवर्ती ग्राहकों को एक खाते में पैसे जमा करने या निकालने की अनुमति देता है, और एक खाते से दूसरे खाते में पैसे ट्रांसफर करने के लिए एक एल्गोरिथम दें। समस्या के पहले भाग का लॉक-आधारित समाधान है: | ||
class Account: | |||
member balance: Integer | |||
member mutex: Lock | |||
method deposit(n: Integer) | |||
mutex.lock() | |||
balance ← balance + n | |||
mutex.unlock() | |||
method withdraw(n: Integer) | |||
deposit(−n) | |||
समस्या का दूसरा भाग कहीं अधिक जटिल है। अनुक्रमिक कार्यक्रमों के लिए सही स्थानांतरण दिनचर्या होगी | समस्या का दूसरा भाग कहीं अधिक जटिल है। अनुक्रमिक कार्यक्रमों के लिए सही स्थानांतरण दिनचर्या होगी | ||
function transfer(from: Account, to: Account, amount: Integer) | |||
from.withdraw(amount) | |||
to.deposit(amount) | |||
एक समवर्ती कार्यक्रम में, यह एल्गोरिदम गलत है क्योंकि जब एक धागा हस्तांतरण के माध्यम से आधे रास्ते में होता है, तो दूसरा यह देख सकता है कि पहले खाते से राशि निकाल ली गई है, लेकिन अभी तक दूसरे खाते में जमा नहीं किया गया है: पैसा सिस्टम से गायब हो गया है। इस समस्या को केवल दो खातों में से किसी एक को बदलने से पहले दोनों खातों पर ताले लगाकर पूरी तरह से ठीक किया जा सकता है, लेकिन फिर गतिरोध को रोकने के लिए कुछ मनमाना, वैश्विक आदेश के अनुसार ताले को लेना होगा: | एक समवर्ती कार्यक्रम में, यह एल्गोरिदम गलत है क्योंकि जब एक धागा हस्तांतरण के माध्यम से आधे रास्ते में होता है, तो दूसरा यह देख सकता है कि पहले खाते से राशि निकाल ली गई है, लेकिन अभी तक दूसरे खाते में जमा नहीं किया गया है: पैसा सिस्टम से गायब हो गया है। इस समस्या को केवल दो खातों में से किसी एक को बदलने से पहले दोनों खातों पर ताले लगाकर पूरी तरह से ठीक किया जा सकता है, लेकिन फिर गतिरोध को रोकने के लिए कुछ मनमाना, वैश्विक आदेश के अनुसार ताले को लेना होगा: | ||
function transfer(from: Account, to: Account, amount: Integer) | |||
if from < to // arbitrary ordering on the locks | |||
from.lock() | |||
to.lock() | |||
else | |||
to.lock() | |||
from.lock() | |||
from.withdraw(amount) | |||
to.deposit(amount) | |||
from.unlock() | |||
to.unlock() | |||
अधिक ताले सम्मलित होने पर यह समाधान अधिक जटिल हो जाता है, और स्थानांतरण फ़ंक्शन को सभी तालों के बारे में जानने की आवश्यकता होती है, इसलिए उन्हें छिपाया नहीं जा सकता। | अधिक ताले सम्मलित होने पर यह समाधान अधिक जटिल हो जाता है, और स्थानांतरण फ़ंक्शन को सभी तालों के बारे में जानने की आवश्यकता होती है, इसलिए उन्हें छिपाया नहीं जा सकता। |
Revision as of 02:07, 7 March 2023
कंप्यूटर विज्ञान में, एक लॉक या म्युटेक्स (पारस्परिक बहिष्कार से) एक तुल्यकालन आदिम है: एक तंत्र जो निष्पादन के कई धागे होने पर संसाधन तक पहुंच पर सीमाएं लागू करता है। एक पारस्परिक बहिष्करण समवर्ती नियंत्रण नीति को लागू करने के लिए एक ताला बनाया गया है, और विभिन्न संभावित विधियों के साथ विभिन्न अनुप्रयोगों के लिए कई अद्वितीय कार्यान्वयन उपस्तिथ है। \\
प्रकार
सामान्यतः, ताले सलाहकार ताले होते है, जहाँ प्रत्येक थ्रेड संबंधित डेटा तक पहुँचने से पहले लॉक को प्राप्त करके सहयोग करता है। कुछ प्रणालियाँ अनिवार्य तालों को भी लागू करती है, जहाँ एक बंद संसाधन तक अनधिकृत पहुँच का प्रयास पहुँच बनाने का प्रयास करने वाली इकाई में एक अपवाद को बाध्य करेगा।
सबसे सरल प्रकार का ताला एक बाइनरी सेमाफोर (प्रोग्रामिंग) है। यह लॉक किए गए डेटा तक विशेष पहुंच प्रदान करता है। अन्य योजनाएँ भी डेटा पढ़ने के लिए साझा पहुँच प्रदान करती है। अन्य व्यापक रूप से लागू किए गए एक्सेस मोड एक्सक्लूसिव, इंटेंट-टू-एक्सक्लूड और इंटेंट-टू-अपग्रेड है।
तालों को वर्गीकृत करने का दूसरी विधि यह है कि क्या होता है जब ताला रणनीति एक धागे की प्रगति को रोकती है। अधिक ांश लॉकिंग डिज़ाइन लॉक का अनुरोध करने वाले थ्रेड के निष्पादन (कंप्यूटर) को तब तक रोकते है जब तक कि उसे लॉक किए गए संसाधन तक पहुँचने की अनुमति न हो। स्पिनलॉक के साथ, थ्रेड केवल तब तक प्रतीक्षा करता है ("स्पिन") जब तक लॉक उपलब्ध नहीं हो जाता। यदि थ्रेड्स थोड़े समय के लिए अवरुद्ध है, तो यह कुशल है, क्योंकि यह ऑपरेटिंग सिस्टम प्रक्रिया के पुनर्निर्धारण के ओवरहेड से बचा जाता है। यह अक्षम है यदि लॉक को लंबे समय तक रखा जाता है, या यदि लॉक को धारण करने वाले थ्रेड की प्रगति लॉक किए गए थ्रेड के प्रीमेशन पर निर्भर करती है।
कुशल कार्यान्वयन के लिए ताले को सामान्यतः हार्डवेयर समर्थन की आवश्यकता होती है। यह समर्थन सामान्यतः एक या एक से अधिक परमाणु (कंप्यूटर विज्ञान) निर्देशों जैसे परीक्षण और सेट, लाने और जोड़ने या तुलना और स्वैप का रूप लेता है। ये निर्देश एकल प्रक्रिया को परीक्षण करने की अनुमति देते है कि क्या लॉक मुक्त है, और यदि मुक्त है, तो एकल परमाणु ऑपरेशन में लॉक प्राप्त करें।
यूनिप्रोसेसर आर्किटेक्चर में निर्देशों के निर्बाध अनुक्रमों का उपयोग करने का विकल्प होता है - अस्थायी रूप से व्यवधानों को अक्षम करने के लिए विशेष निर्देशों या निर्देश उपसर्गों का उपयोग करना - लेकिन यह तकनीक मल्टीप्रोसेसर साझा-मेमोरी मशीनों के लिए काम नहीं करती है। मल्टीप्रोसेसर वातावरण में तालों के लिए उचित समर्थन के लिए अधिक जटिल हार्डवेयर या सॉफ़्टवेयर समर्थन की आवश्यकता हो सकती है, जिसमें पर्याप्त तुल्यकालन समस्याएँ हों।
एक परमाणु संचालन की आवश्यकता का कारण समवर्तीता है, जहां एक से अधिक कार्य एक ही तर्क को निष्पादित करते है। उदाहरण के लिए, निम्नलिखित सी (प्रोग्रामिंग भाषा) कोड पर विचार करें:
if (lock == 0) { // lock free, set it lock = myPID; }
उपरोक्त उदाहरण इस बात की गारंटी नहीं देता है कि कार्य में लॉक है, क्योंकि एक ही समय में एक से अधिक कार्य लॉक का परीक्षण कर सकते है। चूंकि दोनों कार्य यह पता लगाएंगे कि लॉक मुक्त है, दोनों कार्य लॉक को सेट करने का प्रयास करेंगे, बिना यह जाने कि अन्य कार्य भी लॉक सेट कर रहे है। यदि परमाणु लॉकिंग ऑपरेशन उपलब्ध नहीं है तो डेकर या पीटरसन का एल्गोरिदम संभव विकल्प है।
तालों के लापरवाह उपयोग से गतिरोध या लाइवलॉक हो सकता है। डिज़ाइन-टाइम और रन-टाइम दोनों में डेडलॉक्स या लाइवलॉक्स से बचने या पुनर्प्राप्त करने के लिए कई रणनीतियों का उपयोग किया जा सकता है। (सबसे आम रणनीति लॉक अधिग्रहण अनुक्रमों को मानकीकृत करना है जिससे कि अंतर-निर्भर तालों के संयोजन हमेशा विशेष रूप से परिभाषित "कैस्केड" क्रम में प्राप्त किए जा सकें।)
कुछ भाषाएँ सिंटैक्टिक रूप से तालों का समर्थन करती है। सी शार्प में एक उदाहरण इस प्रकार है:
public class Account // This is a monitor of an account { private decimal _balance = 0; private object _balanceLock = new object(); public void Deposit(decimal amount) { // Only one thread at a time may execute this statement. lock (_balanceLock) { _balance += amount; } } public void Withdraw(decimal amount) { // Only one thread at a time may execute this statement. lock (_balanceLock) { _balance -= amount; } } }
कोड lock(this)
यदि उदाहरण को सार्वजनिक रूप से एक्सेस किया जा सकता है तो समस्याएं हो सकती है।[1]
जावा के समान, सीशार्प भी MethodImplOptions.Synchronized विशेषता का उपयोग करके संपूर्ण विधियों को सिंक्रनाइज़ कर सकता है।[2][3]
[MethodImpl(MethodImplOptions.Synchronized)] public void SomeMethod() { // do stuff }
ग्रैन्युलैरिटी
लॉक ग्रैन्युलैरिटी से परिचय कराने से पहले, किसी को लॉक के बारे में तीन अवधारणाओं को समझने की आवश्यकता है:
- लॉक ओवरहेड: तालों का उपयोग करने के लिए अतिरिक्त संसाधन, जैसे कि तालों के लिए आवंटित मेमोरी स्पेस, सीपीयू समय तालों को आरंभ करने और नष्ट करने के लिए, और तालों को प्राप्त करने या जारी करने का समय। एक प्रोग्राम जितना अधिक लॉक का उपयोग करता है, उतना ही अधिक ओवरहेड उपयोग से जुड़ा होता है;
- ताला विवाद: यह तब होता है जब एक प्रक्रिया या थ्रेड किसी अन्य प्रक्रिया या थ्रेड द्वारा रखे गए लॉक को प्राप्त करने का प्रयास करता है। उपलब्ध ताले जितने अधिक महीन होते है, उतनी ही कम संभावना होती है कि एक प्रक्रिया/धागा दूसरे द्वारा रखे गए ताले का अनुरोध करेगा। (उदाहरण के लिए, संपूर्ण तालिका के अतिरिक्त एक पंक्ति को लॉक करना, या संपूर्ण पंक्ति के अतिरिक्त एक सेल को लॉक करना);
- गतिरोध: वह स्थिति जब कम से कम दो कार्यों में से प्रत्येक दूसरे कार्य के लॉक होने की प्रतीक्षा कर रहा हो। जब तक कुछ नहीं किया जाता है, दो कार्य हमेशा के लिए प्रतीक्षा करेंगे।
सिंक्रोनाइज़ेशन में लॉक की संख्या चुनते समय घटते लॉक ओवरहेड और घटते लॉक विवाद के बीच एक ट्रेडऑफ़ होता है।
ताले की एक महत्वपूर्ण संपत्ति इसकी ग्रैन्युलैरिटी है। ग्रैन्युलैरिटी उस डेटा की मात्रा का माप है जिसे लॉक सुरक्षित कर रहा है। सामान्यतः, मोटे ग्रैन्युलैरिटी (तालों की एक छोटी संख्या, प्रत्येक डेटा के एक बड़े खंड की सुरक्षा) का चयन करने से लॉक ओवरहेड कम हो जाता है, जब एक प्रक्रिया संरक्षित डेटा तक पहुंच बना रही होती है, लेकिन खराब प्रदर्शन तब होता है जब कई प्रक्रियाएं समवर्ती रूप से चल रही हों। इसका कारण ताला विवाद का बढ़ना है। ताला जितना अधिक खुरदरा होगा, संभावना उतनी ही अधिक होगी कि ताला एक असंबंधित प्रक्रिया को आगे बढ़ने से रोक देगा। इसके विपरीत, बारीक ग्रैन्युलैरिटी (तालों की एक बड़ी संख्या, प्रत्येक अधिक कम मात्रा में डेटा की रक्षा करता है) का उपयोग करने से तालों का ओवरहेड बढ़ जाता है, लेकिन ताला विवाद कम हो जाता है। ग्रैनुलर लॉकिंग जहां प्रत्येक प्रक्रिया में तालों के एक सामान्य सेट से कई ताले होने चाहिए, सूक्ष्म ताला निर्भरता बना सकते है। यह सूक्ष्मता इस संभावना को बढ़ा सकती है कि एक प्रोग्रामर अनजाने में गतिरोध प्रस्तुत करेगा।
एक डेटाबेस प्रबंधन प्रणाली में, उदाहरण के लिए, एक लॉक ग्रैन्युलैरिटी को कम करने के क्रम में, एक फ़ील्ड, एक फ़ील्ड, एक रिकॉर्ड, एक डेटा पेज या एक संपूर्ण तालिका की रक्षा कर सकता है। मोटे ग्रैन्युलैरिटी, जैसे कि टेबल लॉक का उपयोग करना, एकल उपयोगकर्ता के लिए सर्वश्रेष्ठ प्रदर्शन देने की प्रवृत्ति रखता है, जबकि बारीक ग्रैन्युलैरिटी, जैसे रिकॉर्ड लॉक, कई उपयोगकर्ताओं के लिए सर्वश्रेष्ठ प्रदर्शन देने की प्रवृत्ति रखता है।
डेटाबेस ताले
लेन-देन की समकालिकता सुनिश्चित करने के साधन के रूप में लॉक (डेटाबेस) का उपयोग किया जा सकता है। अर्थात लेन-देन प्रसंस्करण को समवर्ती (इंटरलीविंग लेनदेन) बनाते समय, 2-चरणबद्ध तालों का उपयोग यह सुनिश्चित करता है कि लेन-देन का समवर्ती निष्पादन लेनदेन के कुछ सीरियल ऑर्डरिंग के बराबर हो जाता है। चूँकि, गतिरोध डेटाबेस में लॉकिंग का एक दुर्भाग्यपूर्ण दुष्प्रभाव बन जाता है। लेन-देन के बीच लॉकिंग ऑर्डर को पूर्व-निर्धारित करके डेडलॉक को रोका जा सकता है या वेट-फॉर ग्राफ़ का उपयोग करके पता लगाया जा सकता है। गतिरोध से बचने के दौरान डेटाबेस समकालिकता के लिए लॉकिंग के विकल्प में पूरी तरह से आदेशित वैश्विक टाइमस्टैम्प का उपयोग सम्मलित है।
एक डेटाबेस पर कई समवर्ती उपयोगकर्ताओं के कार्यों को प्रबंधित करने के लिए तंत्र कार्यरत है - इसका उद्देश्य खोए हुए अद्यतनों और गंदे पठन को रोकना है। दो प्रकार के लॉकिंग निराशावादी लॉकिंग और आशावादी लॉकिंग है:
- निराशावादी लॉकिंग: एक उपयोगकर्ता जो इसे अपडेट करने के इरादे से एक रिकॉर्ड पढ़ता है, अन्य उपयोगकर्ताओं को इसमें हेरफेर करने से रोकने के लिए रिकॉर्ड पर एक विशेष लॉक लगाता है। इसका मतलब यह है कि जब तक उपयोगकर्ता लॉक जारी नहीं करता तब तक कोई भी उस रिकॉर्ड में हेरफेर नहीं कर सकता। नकारात्मक पक्ष यह है कि उपयोगकर्ताओं को बहुत लंबे समय के लिए बंद कर दिया जा सकता है, जिससे समग्र प्रणाली की प्रतिक्रिया धीमी हो जाती है और हताशा उत्पन्न होती है।
- निराशावादी लॉकिंग का उपयोग कहाँ करें: यह मुख्य रूप से उन वातावरणों में उपयोग किया जाता है जहाँ डेटा-विवाद (किसी भी समय डेटाबेस सिस्टम के लिए उपयोगकर्ता अनुरोध की डिग्री) भारी है; जहां संगामिति विरोध उत्पन्न होने पर, लॉक के माध्यम से डेटा की सुरक्षा की लागत लेन-देन वापस करने की लागत से कम है। निराशावादी संगामिति सबसे अच्छा तब लागू होती है जब रिकॉर्ड के प्रोग्रामेटिक प्रसंस्करण के रूप में लॉक समय कम होगा। निराशावादी संगामिति के लिए डेटाबेस से लगातार कनेक्शन की आवश्यकता होती है और यह एक स्केलेबल विकल्प नहीं है जब उपयोगकर्ता डेटा के साथ बातचीत कर रहे हों, क्योंकि रिकॉर्ड अपेक्षाकृत बड़ी अवधि के लिए लॉक हो सकते है। यह वेब अनुप्रयोग विकास में उपयोग के लिए उपयुक्त नहीं है।
- ऑप्टिमिस्टिक लॉकिंग: यह कई समवर्ती उपयोगकर्ताओं को डेटाबेस तक पहुंचने की अनुमति देता है, जबकि सिस्टम प्रत्येक उपयोगकर्ता द्वारा किए गए प्रारंभिक-रीड की एक प्रति रखता है। जब कोई उपयोगकर्ता किसी रिकॉर्ड को अपडेट करना चाहता है, तो एप्लिकेशन निर्धारित करता है कि किसी अन्य उपयोगकर्ता ने रिकॉर्ड को पिछली बार पढ़ने के बाद से बदल दिया है या नहीं। एप्लिकेशन रिकॉर्ड में किए गए किसी भी बदलाव को सत्यापित करने के लिए डेटाबेस रिकॉर्ड में मेमोरी में रखे गए प्रारंभिक-रीड की तुलना करके ऐसा करता है। आरंभिक-पठन और डेटाबेस रिकॉर्ड के बीच कोई भी विसंगति समवर्ती नियमों का उल्लंघन करती है और इसलिए सिस्टम को किसी भी अद्यतन अनुरोध की अवहेलना करने का कारण बनता है। एक त्रुटि संदेश उत्पन्न होता है और उपयोगकर्ता को अद्यतन प्रक्रिया फिर से प्रारंभ करने के लिए कहा जाता है। यह आवश्यक लॉकिंग की मात्रा को कम करके डेटाबेस के प्रदर्शन में सुधार करता है, जिससे डेटाबेस सर्वर पर लोड कम होता है। यह उन तालिकाओं के साथ कुशलता से काम करता है जिनके लिए सीमित अपडेट की आवश्यकता होती है क्योंकि कोई भी उपयोगकर्ता लॉक नहीं होता है। चूँकि, कुछ अद्यतन विफल हो सकते है। कई समवर्ती उपयोगकर्ताओं से अद्यतन अनुरोधों की उच्च मात्रा के कारण नकारात्मक पक्ष निरंतर अद्यतन विफलता है - यह उपयोगकर्ताओं के लिए निराशाजनक हो सकता है।
- आशावादी लॉकिंग का उपयोग कहाँ करें: यह उन वातावरणों में उपयुक्त है जहाँ डेटा के लिए कम विवाद है, या जहाँ डेटा तक रीड-ओनली पहुँच की आवश्यकता है। मोबाइल और डिस्कनेक्ट किए गए एप्लिकेशन की जरूरतों को पूरा करने के लिए .NET में ऑप्टिमिस्टिक कंसीडर का व्यापक रूप से उपयोग किया जाता है,[4] जहां लंबे समय तक डेटा पंक्तियों को लॉक करना संभव नहीं होगा। साथ ही, रिकॉर्ड लॉक को बनाए रखने के लिए डेटाबेस सर्वर से लगातार कनेक्शन की आवश्यकता होती है, जो डिस्कनेक्ट किए गए एप्लिकेशन में संभव नहीं है।
नुकसान
लॉक-आधारित संसाधन सुरक्षा और थ्रेड/प्रक्रिया तुल्यकालन के कई नुकसान है:
- विवाद: कुछ धागे/प्रक्रियाओं को लॉक (या ताले का पूरा सेट) जारी होने तक इंतजार करना पड़ता है। यदि लॉक रखने वाले थ्रेड्स में से एक मर जाता है, स्टाल करता है, ब्लॉक करता है, या एक अनंत लूप में प्रवेश करता है, तो लॉक के लिए प्रतीक्षा करने वाले अन्य थ्रेड्स अनिश्चित काल तक प्रतीक्षा कर सकते है जब तक कि कंप्यूटर बिजली साइकिल नहीं हो जाता।
- ओवरहेड: तालों का उपयोग किसी संसाधन तक प्रत्येक पहुंच के लिए ओवरहेड जोड़ता है, तब भी जब टकराव की संभावना बहुत कम होती है। (चूंकि, इस तरह के टकराव की कोई भी संभावना दौड़ की स्थिति है।)
- डिबगिंग: तालों से जुड़े बग समय पर निर्भर होते है और बहुत ही सूक्ष्म और दोहराने में बेहद कठिन हो सकते है, जैसे गतिरोध।
- अस्थिरता: लॉक ओवरहेड और लॉक विवाद के बीच इष्टतम संतुलन समस्या डोमेन (एप्लिकेशन) के लिए अद्वितीय हो सकता है और डिजाइन, कार्यान्वयन और यहां तक कि निम्न-स्तरीय सिस्टम वास्तु परिवर्तन के प्रति संवेदनशील हो सकता है। ये शेष राशि किसी एप्लिकेशन के जीवन चक्र में बदल सकती है और अद्यतन (पुनः संतुलन) के लिए जबरदस्त बदलाव ला सकती है।
- संगति: ताले केवल संगत होते है (उदाहरण के लिए, टेबल ए से वस्तु एक्स को एटोमिकली डिलीट करने के लिए मल्टीपल समवर्ती लॉक्स को मैनेज करना और एक्स को टेबल बी में डालना) अपेक्षाकृत विस्तृत (ओवरहेड) सॉफ्टवेयर सपोर्ट और कठोर सम्मेलनों के लिए प्रोग्रामिंग प्रोग्रामिंग द्वारा सही पालन के साथ।
- प्राथमिकता उलटा: एक सामान्य लॉक रखने वाली कम प्राथमिकता वाली थ्रेड/प्रक्रिया उच्च प्राथमिकता वाले थ्रेड/प्रक्रियाओं को आगे बढ़ने से रोक सकती है। प्राथमिकता-उलटा अवधि को कम करने के लिए प्राथमिकता वंशानुक्रम का उपयोग किया जा सकता है। सबसे खराब स्थिति प्राथमिकता-उलटा अवधि को कम करने के साथ-साथ गतिरोध को रोकने के लिए प्राथमिकता छत प्रोटोकॉल का उपयोग यूनिप्रोसेसर सिस्टम पर किया जा सकता है।
- लॉक काफिला: यदि टाइम-स्लाइस इंटरप्ट या पेज फॉल्ट के कारण लॉक होल्ड करने वाले थ्रेड को शेड्यूल नहीं किया जाता है, तो अन्य सभी थ्रेड्स को इंतजार करना पड़ता है।
कुछ समवर्ती नियंत्रण रणनीतियाँ इनमें से कुछ या सभी समस्याओं से बचती है। उदाहरण के लिए, फ़नल या क्रमबद्ध टोकन सबसे बड़ी समस्या से बच सकते है: गतिरोध। लॉकिंग के विकल्पों में गैर-अवरुद्ध तुल्यकालन विधियाँ सम्मलित है, जैसे लॉक-फ्री प्रोग्रामिंग तकनीक और ट्रांसेक्शनल मेमोरी। चूंकि, ऐसे वैकल्पिक विधियों के लिए अधिकांशतः अधिक आवश्यक होता है कि वास्तविक लॉक तंत्र को ऑपरेटिंग सॉफ़्टवेयर के अधिक मौलिक स्तर पर लागू किया जाए। इसलिए, वे केवल आवेदन स्तर को ताले को लागू करने के विवरण से मुक्त कर सकते है, ऊपर सूचीबद्ध समस्याओं के साथ अभी भी आवेदन के नीचे से निपटने की आवश्यकता है।
ज्यादातर स्थितियों में, उचित लॉकिंग एटॉमिक इंस्ट्रक्शन स्ट्रीम सिंक्रोनाइज़ेशन की एक विधि प्रदान करने वाले सीपीयू पर निर्भर करती है (उदाहरण के लिए, किसी पाइपलाइन में किसी वस्तु को जोड़ने या हटाने के लिए आवश्यक है कि पाइप में अन्य वस्तु जोड़ने या हटाने के लिए आवश्यक सभी समसामयिक संचालन को निलंबित कर दिया जाए। विशिष्ट वस्तु को जोड़ने या हटाने के लिए आवश्यक मेमोरी सामग्री में हेरफेर)। इसलिए, एक एप्लिकेशन अधिकांशतः अधिक मजबूत हो सकता है जब यह एक ऑपरेटिंग सिस्टम पर पड़ने वाले बोझ को पहचानता है और असंभव मांगों की रिपोर्टिंग को शालीनता से पहचानने में सक्षम होता है।
रचनाशीलता का अभाव
लॉक-आधारित प्रोग्रामिंग की सबसे बड़ी समस्याओं में से एक यह है कि "ताले रचना नहीं करते है": मॉड्यूल को संशोधित किए बिना या कम से कम उनके आंतरिक के बारे में जाने बिना छोटे, सही लॉक-आधारित मॉड्यूल को समान रूप से सही बड़े प्रोग्राम में जोड़ना कठिनाई है। साइमन पीटन जोन्स (सॉफ्टवेयर लेनदेन स्मृति के एक वकील) एक बैंकिंग एप्लिकेशन का निम्नलिखित उदाहरण देते है:[5] एक वर्ग खाता डिजाइन करें जो कई समवर्ती ग्राहकों को एक खाते में पैसे जमा करने या निकालने की अनुमति देता है, और एक खाते से दूसरे खाते में पैसे ट्रांसफर करने के लिए एक एल्गोरिथम दें। समस्या के पहले भाग का लॉक-आधारित समाधान है:
class Account: member balance: Integer member mutex: Lock method deposit(n: Integer) mutex.lock() balance ← balance + n mutex.unlock() method withdraw(n: Integer) deposit(−n)
समस्या का दूसरा भाग कहीं अधिक जटिल है। अनुक्रमिक कार्यक्रमों के लिए सही स्थानांतरण दिनचर्या होगी
function transfer(from: Account, to: Account, amount: Integer) from.withdraw(amount) to.deposit(amount)
एक समवर्ती कार्यक्रम में, यह एल्गोरिदम गलत है क्योंकि जब एक धागा हस्तांतरण के माध्यम से आधे रास्ते में होता है, तो दूसरा यह देख सकता है कि पहले खाते से राशि निकाल ली गई है, लेकिन अभी तक दूसरे खाते में जमा नहीं किया गया है: पैसा सिस्टम से गायब हो गया है। इस समस्या को केवल दो खातों में से किसी एक को बदलने से पहले दोनों खातों पर ताले लगाकर पूरी तरह से ठीक किया जा सकता है, लेकिन फिर गतिरोध को रोकने के लिए कुछ मनमाना, वैश्विक आदेश के अनुसार ताले को लेना होगा:
function transfer(from: Account, to: Account, amount: Integer) if from < to // arbitrary ordering on the locks from.lock() to.lock() else to.lock() from.lock() from.withdraw(amount) to.deposit(amount) from.unlock() to.unlock()
अधिक ताले सम्मलित होने पर यह समाधान अधिक जटिल हो जाता है, और स्थानांतरण फ़ंक्शन को सभी तालों के बारे में जानने की आवश्यकता होती है, इसलिए उन्हें छिपाया नहीं जा सकता।
भाषा समर्थन
प्रोग्रामिंग भाषाएँ तुल्यकालन के लिए उनके समर्थन में भिन्न होती है:
- एडा (प्रोग्रामिंग भाषा) संरक्षित वस्तुएँ प्रदान करता है जिनमें दृश्य संरक्षित उपप्रोग्राम या प्रविष्टियाँ[6] और साथ ही मिलन स्थल भी है।[7]
- आईएसओ/आईईसी सी (प्रोग्रामिंग भाषा) मानक सी11 (सी मानक संशोधन) के बाद से एक मानक पारस्परिक बहिष्करण (ताले) अप्लिकेशन प्रोग्रामिंग अंतरफलक प्रदान करता है। वर्तमान आईएसओ/आईईसी सी++ मानक सी++11 से थ्रेडिंग सुविधाओं का समर्थन करता है। ओपनएमपी मानक कुछ कंपाइलरों द्वारा समर्थित है, और प्रागमास का उपयोग करके महत्वपूर्ण वर्गों को निर्दिष्ट करने की अनुमति देता है। पीओएसआईएक्स थ्रेड्स एपीआई लॉक सपोर्ट प्रदान करता है।[8] विजुअल सी ++ प्रदान करता है
synchronize
सिंक्रनाइज़ किए जाने वाले विधियों की विशेषता, लेकिन यह माइक्रोसॉफ़्ट विंडोज़ आर्किटेक्चर और विज़ुअल सी++ कंपाइलर में कॉम ऑब्जेक्ट्स के लिए विशिष्ट है।[9] सी और सी++ किसी भी नेटिव ऑपरेटिंग सिस्टम लॉकिंग फीचर को आसानी से एक्सेस कर सकते है। - सी शार्प (प्रोग्रामिंग भाषा)|सीशार्प प्रदान करता है
lock
किसी संसाधन तक इसकी विशेष पहुंच सुनिश्चित करने के लिए थ्रेड पर कीवर्ड। - सी शार्प संसाधन पर अपनी विशेष पहुंच सुनिश्चित करने के लिए थ्रेड पर लॉक कीवर्ड प्रदान करता है।
- वीबी.नेट सी शार्प के
lock
कीवर्ड की तरह एकSyncLock
कीवर्ड प्रदान करता है। - जावा (प्रोग्रामिंग भाषा) लॉक कोड ब्लॉक, विधियों या वस्तुओं[10] और संगामिति-सुरक्षित डेटा संरचनाओं की विशेषता वाले पुस्तकालयों के लिए
synchronized
किए गए कीवर्ड प्रदान करता है। - उद्देश्य सी कोड के ब्लॉक पर ताले लगाने के लिए
@synchronized
[11] कीवर्ड प्रदान करता है और लॉकिंग के लिए एनएसएलकिंग प्रोटोकॉल[12] के साथ-साथ एनएसलॉक,[13] एनएसरिकर्सिवलॉक,[14] और एनएससींडिशनलॉक[15] कक्षाएं भी प्रदान करता है। - पीएचपी फ़ाइल-आधारित लॉकिंग[16] और साथ ही
pthreads
एक्सटेंशन में एकMutex
क्लास प्रदान करता है।[17] - पायथन (प्रोग्रामिंग भाषा)
threading
मॉड्यूल सेLock
क्लास के साथ एक निम्न-स्तरीय म्यूटेक्स तंत्र प्रदान करता है।[18] - आईएसओ/आईईसी फोरट्रान (प्रोग्रामिंग भाषा) मानक (आईएसओ/आईईसी 1539-1:2010) आंतरिक मॉड्यूल
iso_fortran_env
मेंlock_type
व्युत्पन्न प्रकार और फोरट्रान 2008 के बाद सेlock
/unlock
स्टेटमेंट प्रदान करता है।[19] - रूबी (प्रोग्रामिंग भाषा) निम्न-स्तरीय म्यूचुअल एक्सक्लूजन ऑब्जेक्ट और कोई कीवर्ड नहीं प्रदान करती है।[20]
- जंग (प्रोग्रामिंग भाषा)
Mutex<T>
[21] संरचना प्रदान करता है।[22] - x86 असेंबली उनकी परमाणुता की गारंटी के लिए कुछ परिचालनों पर
LOCK
उपसर्ग प्रदान करती है। - हास्केल (प्रोग्रामिंग भाषा)
MVar
नामक एक परिवर्तनीय डेटा संरचना के माध्यम से लॉकिंग को लागू करता है, जो या तो खाली हो सकता है या इसमें एक मान हो सकता है, सामान्यतः एक संसाधन का संदर्भ। एक थ्रेड जो संसाधन का उपयोग करना चाहता है, एमवीआर का मान लेता है, इसे खाली छोड़ देता है, और इसे समाप्त होने पर वापस रख देता है। खालीMVar
से संसाधन लेने का प्रयास करने से संसाधन उपलब्ध होने तक थ्रेड अवरुद्ध हो जाता है।[23] लॉकिंग के विकल्प के रूप में, सॉफ्टवेयर ट्रांसेक्शनल मेमोरी का कार्यान्वयन भी उपस्तिथ है। - गो (प्रोग्रामिंग भाषा) मानक के पुस्तकालय सिंक पैकेज में एक निम्न-स्तरीय म्यूटेक्स वस्तु प्रदान करता है। [25] इसका उपयोग कोड ब्लॉक, विधियों या वस्तुओं को लॉक करने के लिए किया जा सकता है।
यह भी देखें
- महत्वपूर्ण अनुभाग
- डबल-चेक लॉकिंग
- फाइल लॉकिंग
- लॉक-फ्री और वेट-फ्री एल्गोरिदम
- मॉनिटर (सिंक्रनाइज़ेशन)
- आपसी बहिष्कार
- लॉक पैटर्न पढ़ें/लिखें
संदर्भ
- ↑ "lock Statement (C# Reference)".
- ↑ "ThreadPoolPriority, and MethodImplAttribute". MSDN. p. ??. Retrieved 2011-11-22.
- ↑ "C# From a Java Developer's Perspective". Archived from the original on 2013-01-02. Retrieved 2011-11-22.
- ↑ "Designing Data Tier Components and Passing Data Through Tiers". Microsoft. August 2002. Archived from the original on 2008-05-08. Retrieved 2008-05-30.
- ↑ Peyton Jones, Simon (2007). "Beautiful concurrency" (PDF). In Wilson, Greg; Oram, Andy (eds.). Beautiful Code: Leading Programmers Explain How They Think. O'Reilly.
- ↑ ISO/IEC 8652:2007. "Protected Units and Protected Objects". Ada 2005 Reference Manual. Retrieved 2010-02-27.
A protected object provides coordinated access to shared data, through calls on its visible protected operations, which can be protected subprograms or protected entries.
- ↑ ISO/IEC 8652:2007. "Example of Tasking and Synchronization". Ada 2005 Reference Manual. Retrieved 2010-02-27.
- ↑ Marshall, Dave (March 1999). "Mutual Exclusion Locks". Retrieved 2008-05-30.
- ↑ "Synchronize". msdn.microsoft.com. Retrieved 2008-05-30.
- ↑ "Synchronization". Sun Microsystems. Retrieved 2008-05-30.
- ↑ "Apple Threading Reference". Apple, inc. Retrieved 2009-10-17.
- ↑ "NSLock Reference". Apple, inc. Retrieved 2009-10-17.
- ↑ "NSRecursiveLock Reference". Apple, inc. Retrieved 2009-10-17.
- ↑ "NSConditionLock Reference". Apple, inc. Retrieved 2009-10-17.
- ↑ "NSLocking Protocol Reference". Apple, inc. Retrieved 2009-10-17.
- ↑ "flock".
- ↑ "The Mutex class".
- ↑ Lundh, Fredrik (July 2007). "Thread Synchronization Mechanisms in Python". Archived from the original on 2020-11-01. Retrieved 2008-05-30.
- ↑ John Reid (2010). "Coarrays in the next Fortran Standard" (PDF). Retrieved 2020-02-17.
- ↑ "Programming Ruby: Threads and Processes". 2001. Retrieved 2008-05-30.
- ↑ "std::sync::Mutex - Rust". doc.rust-lang.org. Retrieved 3 November 2020.
- ↑ "Shared-State Concurrency - The Rust Programming Language". doc.rust-lang.org. Retrieved 3 November 2020.
- ↑ Marlow, Simon (August 2013). "Basic concurrency: threads and MVars". हास्केल में समानांतर और समवर्ती प्रोग्रामिंग. O’Reilly Media. ISBN 9781449335946.