കൺകറൻസി നിയന്ത്രണത്തെക്കുറിച്ചുള്ള ആഗോള ഡെവലപ്പർമാർക്കുള്ള സമഗ്രമായ ഗൈഡ്. ലോക്ക്-അധിഷ്ഠിത സമന്വയം, മ്യൂട്ടെക്സുകൾ, സെമഫോറുകൾ, ഡെഡ്ലോക്കുകൾ, മികച്ച രീതികൾ എന്നിവ പര്യവേക്ഷണം ചെയ്യുക.
കൺകറൻസിയിൽ പ്രാവീണ്യം നേടുക: ലോക്ക്-അധിഷ്ഠിത സമന്വയത്തെക്കുറിച്ചുള്ള ആഴത്തിലുള്ള പഠനം
ഒരു തിരക്കേറിയ പ്രൊഫഷണൽ അടുക്കളയെക്കുറിച്ച് ചിന്തിക്കുക. ഒന്നിലധികം ഷെഫുമാർ ഒരേസമയം ജോലിചെയ്യുന്നു, എല്ലാവർക്കും ചേരുവകളുടെ ഒരു പൊതുവായ സംഭരണത്തിലേക്ക് പ്രവേശനം ആവശ്യമാണ്. രണ്ട് ഷെഫുമാർ ഒരേ സമയം ഒരു അപൂർവ സുഗന്ധവ്യഞ്ജനത്തിന്റെ അവസാനത്തെ കുപ്പി എടുക്കാൻ ശ്രമിച്ചാൽ, അത് ആർക്കാണ് ലഭിക്കുക? ഒരു ഷെഫ് ഒരു പാചകക്കുറിപ്പ് കാർഡ് അപ്ഡേറ്റ് ചെയ്യുമ്പോൾ, മറ്റൊരാൾ അത് വായിക്കുകയാണെങ്കിൽ എന്ത് സംഭവിക്കും, ഇത് അർത്ഥമില്ലാത്ത ഒരു നിർദ്ദേശത്തിലേക്ക് കൊണ്ടെത്തിക്കുമോ? ഈ അടുക്കളയിലെ ആശയക്കുഴപ്പം ആധുനിക സോഫ്റ്റ്വെയർ വികസനത്തിലെ പ്രധാന വെല്ലുവിളിക്കുള്ള മികച്ച ഉദാഹരണമാണ്: കൺകറൻസി.
ഇന്നത്തെ മൾട്ടി-കോർ പ്രോസസ്സറുകൾ, വിതരണം ചെയ്ത സിസ്റ്റങ്ങൾ, വളരെ പ്രതികരിക്കുന്ന ആപ്ലിക്കേഷനുകൾ എന്നിവയുടെ ലോകത്ത്, കൺകറൻസി - അന്തിമ ഫലത്തെ ബാധിക്കാതെ ഒരു പ്രോഗ്രാമിന്റെ വ്യത്യസ്ത ഭാഗങ്ങൾ ഭാഗികമായോ ക്രമരഹിതമോ ആയി നടപ്പിലാക്കാനുള്ള കഴിവ് - ഒരു ആഡംബരമല്ല; അതൊരു ആവശ്യകതയാണ്. വേഗതയേറിയ വെബ് സെർവറുകൾ, സുഗമമായ ഉപയോക്തൃ ഇന്റർഫേസുകൾ, ശക്തമായ ഡാറ്റാ പ്രോസസ്സിംഗ് പൈപ്പ്ലൈനുകൾ എന്നിവയുടെ പിന്നിലെ എഞ്ചിനാണിത്. എന്നിരുന്നാലും, ഈ ശക്തിക്ക് കാര്യമായ സങ്കീർണ്ണതകളുണ്ട്. ഒന്നിലധികം ത്രെഡുകളോ പ്രോസസ്സുകളോ പങ്കിട്ട ഉറവിടങ്ങൾ ഒരേസമയം ആക്സസ് ചെയ്യുമ്പോൾ, അവ പരസ്പരം ഇടപെടുകയും, കേടായ ഡാറ്റയിലേക്കും, പ്രവചനാതീതമായ പെരുമാറ്റത്തിലേക്കും, നിർണായകമായ സിസ്റ്റം പരാജയങ്ങളിലേക്കും നയിച്ചേക്കാം. ഇവിടെയാണ് കൺകറൻസി നിയന്ത്രണം വരുന്നത്.
ഈ സമഗ്രമായ ഗൈഡ് ഈ നിയന്ത്രിത ആശയക്കുഴപ്പം കൈകാര്യം ചെയ്യുന്നതിനുള്ള ഏറ്റവും അടിസ്ഥാനപരവും വ്യാപകമായി ഉപയോഗിക്കപ്പെടുന്നതുമായ സാങ്കേതികത പര്യവേക്ഷണം ചെയ്യും: ലോക്ക്-അധിഷ്ഠിത സമന്വയം. ലോക്കുകൾ എന്താണെന്ന് ഞങ്ങൾ വ്യക്തമാക്കുകയും, അവയുടെ വിവിധ രൂപങ്ങൾ പര്യവേക്ഷണം ചെയ്യുകയും, അവയുടെ അപകടകരമായ കുഴികൾ നാവിഗേറ്റ് ചെയ്യുകയും, ശക്തവും സുരക്ഷിതവും കാര്യക്ഷമവുമായ കൺകറൻ്റ് കോഡ് എഴുതുന്നതിനുള്ള ഒരു കൂട്ടം ആഗോള മികച്ച രീതികൾ സ്ഥാപിക്കുകയും ചെയ്യും.
എന്താണ് കൺകറൻസി നിയന്ത്രണം?
അതിൻ്റെ കാതലിൽ, കൺകറൻസി നിയന്ത്രണം എന്നത് കമ്പ്യൂട്ടർ സയൻസിലെ ഒരു വിഷയമാണ്, പങ്കിട്ട ഡാറ്റയിലെ ഒരേസമയം നടക്കുന്ന പ്രവർത്തനങ്ങൾ കൈകാര്യം ചെയ്യാൻ ഇത് സമർപ്പിക്കപ്പെട്ടിരിക്കുന്നു. കൺകറൻ്റ് പ്രവർത്തനങ്ങൾ പരസ്പരം ഇടപെടാതെ ശരിയായി നടപ്പിലാക്കുന്നു എന്ന് ഉറപ്പാക്കുക എന്നതാണ് ഇതിന്റെ പ്രധാന ലക്ഷ്യം, ഡാറ്റയുടെ സമഗ്രതയും സ്ഥിരതയും നിലനിർത്തുന്നു. ഇത് എങ്ങനെയാണ് പാചകക്കാർക്ക് ചേരുവകൾ കിട്ടുന്നത്, കൂടാതെ ഉണ്ടാകുന്ന പ്രശ്നങ്ങളും, പാഴായിപ്പോകുന്ന ചേരുവകളും ഒഴിവാക്കാൻ അടുക്കള മാനേജർ നിയമങ്ങൾ ഉണ്ടാക്കുന്നത് എന്ന് ചിന്തിക്കുക.
ഡാറ്റാബേസുകളുടെ ലോകത്ത്, ACID പ്രോപ്പർട്ടികൾ (ആറ്റോമിസിറ്റി, സ്ഥിരത, ഐസൊലേഷൻ, ഡ്യൂറബിലിറ്റി) നിലനിർത്തുന്നതിന് കൺകറൻസി നിയന്ത്രണം അത്യാവശ്യമാണ്, പ്രത്യേകിച്ചും ഐസൊലേഷൻ. ഇടപാടുകളുടെ കൺകറൻ്റ് എക്സിക്യൂഷൻ ഇടപാടുകൾ തുടർച്ചയായി ഒന്നൊന്നായി നടപ്പിലാക്കിയാൽ ലഭിക്കുന്ന ഒരു സിസ്റ്റം അവസ്ഥയിലേക്ക് വരുമെന്ന് ഐസൊലേഷൻ ഉറപ്പാക്കുന്നു.
കൺകറൻസി നിയന്ത്രണം നടപ്പിലാക്കുന്നതിനുള്ള രണ്ട് പ്രധാന തത്വങ്ങൾ ഇതാ:
- ഒപ്റ്റിമിസ്റ്റിക് കൺകറൻസി നിയന്ത്രണം: ഈ സമീപനം, വൈരുദ്ധ്യങ്ങൾ വളരെ കുറവാണെന്ന് അനുമാനിക്കുന്നു. മുൻകൂട്ടിയുള്ള പരിശോധനകളില്ലാതെ പ്രവർത്തനങ്ങൾ തുടരാൻ ഇത് അനുവദിക്കുന്നു. ഒരു മാറ്റം വരുത്തുന്നതിന് മുമ്പ്, മറ്റൊരു പ്രവർത്തനം ഇതിനകം ഡാറ്റയിൽ മാറ്റം വരുത്തിയിട്ടുണ്ടോ എന്ന് സിസ്റ്റം പരിശോധിക്കുന്നു. ഒരു വൈരുദ്ധ്യം കണ്ടെത്തിയാൽ, പ്രവർത്തനം സാധാരണയായി പഴയപടിയാക്കുകയും വീണ്ടും ശ്രമിക്കുകയും ചെയ്യും. ഇതൊരു "ക്ഷമ ചോദിക്കുക, അനുമതി ചോദിക്കരുത്" തന്ത്രമാണ്.
- പെസിമിസ്റ്റിക് കൺകറൻസി നിയന്ത്രണം: ഈ സമീപനം, വൈരുദ്ധ്യങ്ങൾ ഉണ്ടാകാൻ സാധ്യതയുണ്ടെന്ന് അനുമാനിക്കുന്നു. ഒരു റിസോഴ്സിലേക്ക് പ്രവേശിക്കുന്നതിന് മുമ്പ് അതിൽ ഒരു ലോക്ക് നേടാൻ ഇത് ഒരു പ്രവർത്തനത്തെ നിർബന്ധിക്കുന്നു, ഇത് മറ്റ് പ്രവർത്തനങ്ങളെ ഇടപെടാതെ തടയുന്നു. ഇതൊരു "അനുമതി ചോദിക്കുക, ക്ഷമ ചോദിക്കരുത്" തന്ത്രമാണ്.
ഈ ലേഖനം ലോക്ക്-അധിഷ്ഠിത സമന്വയത്തിന്റെ അടിസ്ഥാനമായ, പെസിമിസ്റ്റിക് സമീപനത്തിൽ മാത്രമാണ് ശ്രദ്ധ കേന്ദ്രീകരിക്കുന്നത്.
പ്രധാന പ്രശ്നം: റേസ് അവസ്ഥകൾ
പരിഹാരം മനസ്സിലാക്കുന്നതിന് മുമ്പ്, നമ്മൾ പ്രശ്നം പൂർണ്ണമായി മനസ്സിലാക്കണം. കൺകറൻ്റ് പ്രോഗ്രാമിംഗിലെ ഏറ്റവും സാധാരണവും അപകടകരവുമായ ബഗ് റേസ് അവസ്ഥയാണ്. ഒരു റേസ് അവസ്ഥ ഉണ്ടാകുന്നത്, ഒരു സിസ്റ്റത്തിന്റെ പെരുമാറ്റം, ഓപ്പറേറ്റിംഗ് സിസ്റ്റം ത്രെഡുകൾ ഷെഡ്യൂൾ ചെയ്യുന്നത് പോലുള്ള, നിയന്ത്രിക്കാനാവാത്ത സംഭവങ്ങളുടെ പ്രവചനാതീതമായ ക്രമത്തെ ആശ്രയിച്ചിരിക്കുമ്പോഴാണ്.
ഒരു പൊതുവായ ബാങ്ക് അക്കൗണ്ടിന്റെ ഉദാഹരണം പരിഗണിക്കാം. ഒരു അക്കൗണ്ടിൽ 1000 ഡോളർ ബാലൻസ് ഉണ്ടെന്നും, രണ്ട് കൺകറൻ്റ് ത്രെഡുകൾ 100 ഡോളർ വീതം നിക്ഷേപിക്കാൻ ശ്രമിക്കുന്നു എന്നും കരുതുക.
നിക്ഷേപത്തിനായുള്ള പ്രവർത്തനങ്ങളുടെ ലളിതമായ ശ്രേണി ഇതാ:
- മെമ്മറിയിൽ നിന്ന് നിലവിലെ ബാലൻസ് വായിക്കുക.
- ഈ മൂല്യത്തിലേക്ക് നിക്ഷേപ തുക ചേർക്കുക.
- പുതിയ മൂല്യം മെമ്മറിയിലേക്ക് തിരികെ എഴുതുക.
ഒരു ശരിയായ, സീരിയൽ എക്സിക്യൂഷൻ 1200 ഡോളർ അന്തിമ ബാലൻസിൽ കലാശിക്കും. എന്നാൽ ഒരു കൺകറൻ്റ് സാഹചര്യത്തിൽ എന്ത് സംഭവിക്കും?
പ്രവർത്തനങ്ങളുടെ ഒരു സാധ്യതയുള്ള ഇടപെടൽ:
- ത്രെഡ് എ: ബാലൻസ് വായിക്കുന്നു (1000 ഡോളർ).
- സന്ദർഭ സ്വിച്ച്: ഓപ്പറേറ്റിംഗ് സിസ്റ്റം ത്രെഡ് എ താൽക്കാലികമായി നിർത്തി ത്രെഡ് ബി പ്രവർത്തിപ്പിക്കുന്നു.
- ത്രെഡ് ബി: ബാലൻസ് വായിക്കുന്നു (ഇപ്പോഴും 1000 ഡോളർ).
- ത്രെഡ് ബി: അതിൻ്റെ പുതിയ ബാലൻസ് കണക്കാക്കുന്നു (1000 + 100 = 1100 ഡോളർ).
- ത്രെഡ് ബി: പുതിയ ബാലൻസ് (1100 ഡോളർ) മെമ്മറിയിലേക്ക് തിരികെ എഴുതുന്നു.
- സന്ദർഭ സ്വിച്ച്: ഓപ്പറേറ്റിംഗ് സിസ്റ്റം ത്രെഡ് എ പുനരാരംഭിക്കുന്നു.
- ത്രെഡ് എ: ഇത് മുമ്പ് വായിച്ച മൂല്യത്തെ അടിസ്ഥാനമാക്കി അതിൻ്റെ പുതിയ ബാലൻസ് കണക്കാക്കുന്നു (1000 + 100 = 1100 ഡോളർ).
- ത്രെഡ് എ: പുതിയ ബാലൻസ് (1100 ഡോളർ) മെമ്മറിയിലേക്ക് തിരികെ എഴുതുന്നു.
അന്തിമ ബാലൻസ് 1200 ഡോളർ അല്ല, 1100 ഡോളറാണ്. റേസ് അവസ്ഥ കാരണം 100 ഡോളർ നിക്ഷേപം ഇല്ലാതായി. പങ്കിട്ട റിസോഴ്സ് (അക്കൗണ്ട് ബാലൻസ്) ആക്സസ് ചെയ്യുന്ന കോഡിന്റെ ഭാഗത്തെ ക്രിട്ടിക്കൽ സെക്ഷൻ എന്ന് വിളിക്കുന്നു. റേസ് അവസ്ഥകൾ തടയുന്നതിന്, ഒരു സമയം ഒരു ത്രെഡിന് മാത്രമേ ക്രിട്ടിക്കൽ സെക്ഷനിൽ എക്സിക്യൂട്ട് ചെയ്യാൻ കഴിയൂ എന്ന് ഉറപ്പാക്കണം. ഈ തത്വമാണ് പരസ്പര ഒഴിവാക്കൽ എന്ന് അറിയപ്പെടുന്നത്.
ലോക്ക്-അധിഷ്ഠിത സമന്വയം പരിചയപ്പെടുത്തുന്നു
പരസ്പര ഒഴിവാക്കൽ നടപ്പിലാക്കുന്നതിനുള്ള പ്രധാന സംവിധാനമാണ് ലോക്ക്-അധിഷ്ഠിത സമന്വയം. ഒരു ലോക്ക് (ഒരു മ്യൂട്ടെക്സ് എന്നും അറിയപ്പെടുന്നു) ഒരു ക്രിട്ടിക്കൽ സെക്ഷന്റെ കാവൽക്കാരനായി പ്രവർത്തിക്കുന്ന ഒരു സമന്വയ പ്രിമിറ്റീവാണ്.
ഒരു ശുചിമുറിയിലേക്കുള്ള താക്കോലിന്റെ ഉപമ വളരെ ഉചിതമാണ്. ശുചിമുറി ക്രിട്ടിക്കൽ സെക്ഷനും താക്കോൽ ലോക്കുമാണ്. നിരവധി ആളുകൾ (ത്രെഡുകൾ) പുറത്ത് കാത്തിരിക്കാം, എന്നാൽ താക്കോൽ കൈവശം വച്ചിരിക്കുന്ന വ്യക്തിക്ക് മാത്രമേ പ്രവേശിക്കാൻ കഴിയൂ. അവർ പൂർത്തിയാകുമ്പോൾ, അവർ പുറത്തുകടക്കുകയും താക്കോൽ തിരികെ നൽകുകയും ചെയ്യുന്നു, ഇത് അടുത്തയാൾക്ക് എടുക്കാനും പ്രവേശിക്കാനും അനുവദിക്കുന്നു.
ലോക്കുകൾ രണ്ട് അടിസ്ഥാന പ്രവർത്തനങ്ങളെ പിന്തുണയ്ക്കുന്നു:
- നേടുക (അല്ലെങ്കിൽ ലോക്ക്): ഒരു ക്രിട്ടിക്കൽ സെക്ഷനിൽ പ്രവേശിക്കുന്നതിന് മുമ്പ് ഒരു ത്രെഡ് ഈ പ്രവർത്തനം വിളിക്കുന്നു. ലോക്ക് ലഭ്യമാണെങ്കിൽ, ത്രെഡ് അത് നേടുകയും തുടരുകയും ചെയ്യുന്നു. ലോക്ക് ഇതിനകം മറ്റൊരു ത്രെഡ് കൈവശം വെച്ചിട്ടുണ്ടെങ്കിൽ, ലോക്ക് റിലീസ് ചെയ്യുന്നതുവരെ കോളിംഗ് ത്രെഡ് തടയും (അല്ലെങ്കിൽ "ഉറങ്ങും").
- റിലീസ് ചെയ്യുക (അല്ലെങ്കിൽ അൺലോക്ക് ചെയ്യുക): ക്രിട്ടിക്കൽ സെക്ഷൻ എക്സിക്യൂട്ട് ചെയ്യുന്നത് പൂർത്തിയാക്കിയ ശേഷം ഒരു ത്രെഡ് ഈ പ്രവർത്തനം വിളിക്കുന്നു. ഇത് മറ്റ് കാത്തിരിക്കുന്ന ത്രെഡുകൾക്ക് നേടാൻ ലോക്ക് ലഭ്യമാക്കുന്നു.
ഞങ്ങളുടെ ബാങ്ക് അക്കൗണ്ട് ലോജിക് ഒരു ലോക്ക് ഉപയോഗിച്ച് പൊതിഞ്ഞ്, നമുക്ക് അതിൻ്റെ കൃത്യത ഉറപ്പാക്കാൻ കഴിയും:
acquire_lock(account_lock);
// --- Critical Section Start ---
balance = read_balance();
new_balance = balance + amount;
write_balance(new_balance);
// --- Critical Section End ---
release_lock(account_lock);
ഇപ്പോൾ, ത്രെഡ് എ ആദ്യം ലോക്ക് നേടിയാൽ, ത്രെഡ് എ എല്ലാ മൂന്ന് ഘട്ടങ്ങളും പൂർത്തിയാക്കി ലോക്ക് റിലീസ് ചെയ്യുന്നതുവരെ ത്രെഡ് ബി കാത്തിരിക്കേണ്ടിവരും. പ്രവർത്തനങ്ങൾ ഇനി പരസ്പരം ചേർന്ന് ചെയ്യില്ല, കൂടാതെ റേസ് അവസ്ഥയും ഇല്ലാതാകും.
ലോക്കുകളുടെ തരങ്ങൾ: പ്രോഗ്രാമറുടെ ടൂൾകിറ്റ്
ഒരു ലോക്കിന്റെ അടിസ്ഥാന ആശയം ലളിതമാണെങ്കിലും, വ്യത്യസ്ത സാഹചര്യങ്ങളിൽ വ്യത്യസ്ത തരം ലോക്കിംഗ് സംവിധാനങ്ങൾ ആവശ്യമാണ്. ലഭ്യമായ ലോക്കുകളുടെ ടൂൾകിറ്റ് മനസ്സിലാക്കുന്നത് കാര്യക്ഷമവും ശരിയായതുമായ കൺകറൻ്റ് സിസ്റ്റങ്ങൾ നിർമ്മിക്കുന്നതിന് നിർണായകമാണ്.
മ്യൂട്ടെക്സ് (പരസ്പര ഒഴിവാക്കൽ) ലോക്കുകൾ
ഒരു മ്യൂട്ടെക്സ് ഏറ്റവും ലളിതവും സാധാരണവുമായ ലോക്കാണ്. ഇതൊരു ബൈനറി ലോക്കാണ്, അതായത് ഇതിന് രണ്ട് അവസ്ഥകളേ ഉണ്ടാകൂ: ലോക്ക് ചെയ്തു അല്ലെങ്കിൽ അൺലോക്ക് ചെയ്തു. കർശനമായ പരസ്പര ഒഴിവാക്കൽ നടപ്പിലാക്കാൻ ഇത് രൂപകൽപ്പന ചെയ്തിട്ടുള്ളതാണ്, ഒരു സമയം ഒരു ത്രെഡിന് മാത്രമേ ലോക്ക് സ്വന്തമാക്കാൻ കഴിയൂ എന്ന് ഉറപ്പാക്കുന്നു.
- ഉടമസ്ഥാവകാശം: മിക്ക മ്യൂട്ടെക്സ് നടപ്പാക്കലിന്റെയും ഒരു പ്രധാന സവിശേഷത ഉടമസ്ഥാവകാശമാണ്. മ്യൂട്ടെക്സ് നേടുന്ന ത്രെഡിന് മാത്രമേ ഇത് റിലീസ് ചെയ്യാൻ കഴിയൂ. ഇത് മറ്റൊരു ത്രെഡ് ഉപയോഗിക്കുന്ന ഒരു ക്രിട്ടിക്കൽ സെക്ഷൻ അശ്രദ്ധമായി (അല്ലെങ്കിൽ ദോഷകരമായി) അൺലോക്ക് ചെയ്യുന്നത് തടയുന്നു.
- ഉപയോഗ കേസ്: ഒരു ഷെയർഡ് വേരിയബിൾ അപ്ഡേറ്റ് ചെയ്യുകയോ ഒരു ഡാറ്റാ ഘടന പരിഷ്കരിക്കുകയോ ചെയ്യുന്നത് പോലുള്ള ലളിതമായ ക്രിട്ടിക്കൽ സെക്ഷനുകൾ പരിരക്ഷിക്കുന്നതിനുള്ള ഡിഫോൾട്ട് ചോയിസാണ് മ്യൂട്ടെക്സുകൾ.
സെമഫോറുകൾ
ഡച്ച് കമ്പ്യൂട്ടർ ശാസ്ത്രജ്ഞനായ എഡ്സ്ഗർ ഡബ്ല്യു. ഡിജസ്ട്ര കണ്ടുപിടിച്ച ഒരു പൊതുവായ സമന്വയ പ്രിമിറ്റീവാണ് സെമഫോർ. ഒരു മ്യൂട്ടെക്സിൽ നിന്ന് വ്യത്യസ്തമായി, ഒരു സെമഫോർ നെഗറ്റീവ് ഇല്ലാത്ത ഒരു പൂർണ്ണസംഖ്യയുടെ കൗണ്ടർ നിലനിർത്തുന്നു.
ഇത് രണ്ട് ആറ്റോമിക് പ്രവർത്തനങ്ങളെ പിന്തുണയ്ക്കുന്നു:
- wait() (അല്ലെങ്കിൽ പി പ്രവർത്തനം): സെമഫോറിന്റെ കൗണ്ടർ കുറയ്ക്കുന്നു. കൗണ്ടർ നെഗറ്റീവ് ആയാൽ, കൗണ്ടർ പൂജ്യത്തിന് മുകളിലോ തുല്യമോ ആകുന്നതുവരെ ത്രെഡ് തടയും.
- signal() (അല്ലെങ്കിൽ വി പ്രവർത്തനം): സെമഫോറിന്റെ കൗണ്ടർ വർദ്ധിപ്പിക്കുന്നു. സെമഫോറിൽ തടഞ്ഞ ഏതെങ്കിലും ത്രെഡുകൾ ഉണ്ടെങ്കിൽ, അവയിലൊന്നിനെ തടയും.
പ്രധാനമായും രണ്ട് തരം സെമഫോറുകൾ ഉണ്ട്:
- ബൈനറി സെമഫോർ: കൗണ്ടർ 1 ആയി ആരംഭിക്കുന്നു. ഇതിന് 0 അല്ലെങ്കിൽ 1 ആയിരിക്കാൻ കഴിയും, ഇത് ഒരു മ്യൂട്ടെക്സിന് തുല്യമാക്കുന്നു.
- കൗണ്ടിംഗ് സെമഫോർ: കൗണ്ടർ ഏതെങ്കിലും പൂർണ്ണസംഖ്യ N > 1 ആയി ആരംഭിക്കാൻ കഴിയും. ഇത് N വരെ ത്രെഡുകൾക്ക് ഒരേസമയം ഒരു റിസോഴ്സ് ആക്സസ് ചെയ്യാൻ അനുവദിക്കുന്നു. പരിമിതമായ റിസോഴ്സുകളുടെ ഒരു പൂളിലേക്കുള്ള ആക്സസ് നിയന്ത്രിക്കാൻ ഇത് ഉപയോഗിക്കുന്നു.
ഉദാഹരണം: പരമാവധി 10 കൺകറൻ്റ് ഡാറ്റാബേസ് കണക്ഷനുകൾ കൈകാര്യം ചെയ്യാൻ കഴിയുന്ന ഒരു വെബ് ആപ്ലിക്കേഷൻ ഉണ്ടെന്ന് കരുതുക. 10 ആയി ആരംഭിക്കുന്ന ഒരു കൗണ്ടിംഗ് സെമഫോറിന് ഇത് നന്നായി കൈകാര്യം ചെയ്യാൻ കഴിയും. ഓരോ ത്രെഡും ഒരു കണക്ഷൻ എടുക്കുന്നതിന് മുമ്പ് സെമഫോറിൽ ഒരു `wait()` നടത്തണം. പതിനൊന്നാമത്തെ ത്രെഡ് തടയും, ആദ്യത്തെ 10 ത്രെഡുകളിലൊന്ന് അതിൻ്റെ ഡാറ്റാബേസ് വർക്ക് പൂർത്തിയാക്കുകയും സെമഫോറിൽ ഒരു `signal()` നടത്തുകയും ചെയ്യുന്നത് വരെ, കണക്ഷൻ പൂളിലേക്ക് തിരികെ നൽകും.
റീഡ്-റൈറ്റ് ലോക്കുകൾ (പങ്കിട്ട/എക്സ്ക്ലൂസീവ് ലോക്കുകൾ)
കൺകറൻ്റ് സിസ്റ്റങ്ങളിൽ ഒരു പൊതുവായ രീതി, ഡാറ്റ എഴുതുന്നതിനേക്കാൾ കൂടുതൽ തവണ വായിക്കപ്പെടുന്നു എന്നതാണ്. ഈ സാഹചര്യത്തിൽ ഒരു ലളിതമായ മ്യൂട്ടെക്സ് ഉപയോഗിക്കുന്നത് കാര്യക്ഷമമല്ലാത്ത ഒന്നാണ്, കാരണം ഒന്നിലധികം ത്രെഡുകൾ ഒരേസമയം ഡാറ്റ വായിക്കുന്നത് ഇത് തടയുന്നു, എന്നിരുന്നാലും വായന സുരക്ഷിതവും, മാറ്റം വരുത്താത്തതുമാണ്.
ഒരു റീഡ്-റൈറ്റ് ലോക്ക് രണ്ട് ലോക്കിംഗ് മോഡുകൾ നൽകി ഇതിനെ അഭിസംബോധന ചെയ്യുന്നു:
- പങ്കിട്ട (റീഡ്) ലോക്ക്: റൈറ്റ് ലോക്ക് ഒന്നും ഇല്ലാത്തപ്പോൾ, ഒന്നിലധികം ത്രെഡുകൾക്ക് ഒരേസമയം ഒരു റീഡ് ലോക്ക് നേടാനാകും. ഇത് ഉയർന്ന കൺകറൻസി വായനയ്ക്ക് അനുവദിക്കുന്നു.
- എക്സ്ക്ലൂസീവ് (റൈറ്റ്) ലോക്ക്: ഒരു സമയം ഒരു ത്രെഡിന് മാത്രമേ ഒരു റൈറ്റ് ലോക്ക് നേടാൻ കഴിയൂ. ഒരു ത്രെഡ് ഒരു റൈറ്റ് ലോക്ക് കൈവശം വെച്ചിരിക്കുമ്പോൾ, മറ്റ് എല്ലാ ത്രെഡുകളും (റീഡർമാരും റൈറ്റർമാരും) തടയപ്പെടും.
ഒരു ഷെയർഡ് ലൈബ്രറിയിലെ ഒരു ഡോക്യുമെൻ്റാണ് ഇതിന് ഉദാഹരണം. നിരവധി ആളുകൾക്ക് ഒരേ സമയം ഡോക്യുമെൻ്റിൻ്റെ പകർപ്പുകൾ വായിക്കാൻ കഴിയും (പങ്കിട്ട റീഡ് ലോക്ക്). എന്നിരുന്നാലും, ആരെങ്കിലും ഡോക്യുമെൻ്റ് എഡിറ്റ് ചെയ്യാൻ ആഗ്രഹിക്കുന്നുവെങ്കിൽ, അവർ അത് എക്സ്ക്ലൂസീവായി പരിശോധിക്കണം, കൂടാതെ മറ്റാർക്കും ഇത് പൂർത്തിയാകുന്നതുവരെ വായിക്കാനോ എഡിറ്റ് ചെയ്യാനോ കഴിയില്ല (എക്സ്ക്ലൂസീവ് റൈറ്റ് ലോക്ക്).
റിഗേർസീവ് ലോക്കുകൾ (റീഎൻട്രന്റ് ലോക്കുകൾ)
ഒരു മ്യൂട്ടെക്സ് ഇതിനകം കൈവശം വെച്ചിട്ടുള്ള ഒരു ത്രെഡ് അത് വീണ്ടും നേടാൻ ശ്രമിച്ചാൽ എന്ത് സംഭവിക്കും? ഒരു സാധാരണ മ്യൂട്ടെക്സ് ഉപയോഗിച്ച്, ഇത് തൽക്ഷണമായ ഒരു ഡെഡ്ലോക്കിൽ കലാശിക്കും - ത്രെഡ് ലോക്ക് റിലീസ് ചെയ്യുന്നതിനായി എന്നേക്കും കാത്തിരിക്കും. ഒരു റിഗേർസീവ് ലോക്ക് (അല്ലെങ്കിൽ റീഎൻട്രന്റ് ലോക്ക്) ഈ പ്രശ്നം പരിഹരിക്കാൻ രൂപകൽപ്പന ചെയ്തതാണ്.
ഒരു റിഗേർസീവ് ലോക്ക് ഒരേ ത്രെഡിനെ ഒരേ ലോക്ക് ഒന്നിലധികം തവണ നേടാൻ അനുവദിക്കുന്നു. ഇത് ഒരു ആന്തരിക ഉടമസ്ഥാവകാശ കൗണ്ടർ നിലനിർത്തുന്നു. ഉടമസ്ഥതയിലുള്ള ത്രെഡ് `acquire()` എന്ന് വിളിച്ച അതേ എണ്ണം തവണ `release()` എന്ന് വിളിക്കുമ്പോൾ മാത്രമേ ലോക്ക് പൂർണ്ണമായി റിലീസ് ചെയ്യുകയുള്ളൂ. ഇത് എക്സിക്യൂഷൻ സമയത്ത് ഒരു പങ്കിട്ട റിസോഴ്സ് പരിരക്ഷിക്കേണ്ട റിഗേർസീവ് ഫംഗ്ഷനുകളിൽ പ്രത്യേകിച്ചും ഉപയോഗപ്രദമാണ്.
ലോക്കിംഗിന്റെ അപകടങ്ങൾ: സാധാരണ അപകടങ്ങൾ
ലോക്കുകൾ ശക്തമാണെങ്കിലും, അവ ഒരുപോലെ മൂർച്ചയുള്ള വാളുകളാണ്. ലോക്കുകളുടെ ശരിയായ ഉപയോഗമില്ലായ്മ, ലളിതമായ റേസ് അവസ്ഥകളെക്കാൾ കണ്ടെത്താനും പരിഹരിക്കാനും വളരെ ബുദ്ധിമുട്ടുള്ള ബഗുകളിലേക്ക് നയിച്ചേക്കാം. ഇവയിൽ ഡെഡ്ലോക്കുകൾ, ലിവെലോക്കുകൾ, പ്രകടനത്തിലെ കുറവുകൾ എന്നിവ ഉൾപ്പെടുന്നു.
ഡെഡ്ലോക്ക്
കൺകറൻ്റ് പ്രോഗ്രാമിംഗിൽ ഏറ്റവും ഭയപ്പെടുന്ന സാഹചര്യമാണ് ഡെഡ്ലോക്ക്. രണ്ട് അല്ലെങ്കിൽ അതിലധികമോ ത്രെഡുകൾ അനിശ്ചിതമായി തടയുമ്പോൾ ഇത് സംഭവിക്കുന്നു, ഓരോന്നും ഒരേ സെറ്റിലെ മറ്റൊരു ത്രെഡ് കൈവശം വെച്ചിരിക്കുന്ന ഒരു റിസോഴ്സിനായി കാത്തിരിക്കുന്നു.
രണ്ട് ത്രെഡുകളും (ത്രെഡ് 1, ത്രെഡ് 2), രണ്ട് ലോക്കുകളും (ലോക്ക് എ, ലോക്ക് ബി) ഉള്ള ഒരു ലളിതമായ സാഹചര്യം പരിഗണിക്കുക:
- ത്രെഡ് 1 ലോക്ക് എ നേടുന്നു.
- ത്രെഡ് 2 ലോക്ക് ബി നേടുന്നു.
- ത്രെഡ് 1 ഇപ്പോൾ ലോക്ക് ബി നേടാൻ ശ്രമിക്കുന്നു, എന്നാൽ ഇത് ത്രെഡ് 2 കൈവശം വെച്ചിരിക്കുന്നു, അതിനാൽ ത്രെഡ് 1 തടയുന്നു.
- ത്രെഡ് 2 ഇപ്പോൾ ലോക്ക് എ നേടാൻ ശ്രമിക്കുന്നു, എന്നാൽ ഇത് ത്രെഡ് 1 കൈവശം വെച്ചിരിക്കുന്നു, അതിനാൽ ത്രെഡ് 2 തടയുന്നു.
രണ്ട് ത്രെഡുകളും ഇപ്പോൾ ഒരു സ്ഥിരമായ കാത്തിരിപ്പ് അവസ്ഥയിൽ കുടുങ്ങിയിരിക്കുന്നു. ആപ്ലിക്കേഷൻ നിലയ്ക്കുന്നു. ഈ സാഹചര്യം നാല് ആവശ്യമായ വ്യവസ്ഥകളുടെ സാന്നിധ്യത്തിൽ നിന്നാണ് ഉണ്ടാകുന്നത് (കോഫ്മാൻ വ്യവസ്ഥകൾ):
- പരസ്പര ഒഴിവാക്കൽ: റിസോഴ്സുകൾ (ലോക്കുകൾ) പങ്കിടാൻ കഴിയില്ല.
- ഹോൾഡ് ആൻഡ് വെയിറ്റ്: മറ്റൊരു റിസോഴ്സിനായി കാത്തിരിക്കുമ്പോൾ ഒരു ത്രെഡ് കുറഞ്ഞത് ഒരു റിസോഴ്സെങ്കിലും കൈവശം വെക്കുന്നു.
- നോ പ്രീemption: ഒരു റിസോഴ്സ്, അത് കൈവശം വെച്ചിരിക്കുന്ന ഒരു ത്രെഡിൽ നിന്ന് ബലമായി എടുക്കാൻ കഴിയില്ല.
- സർക്കുലർ വെയിറ്റ്: രണ്ട് അല്ലെങ്കിൽ അതിലധികമോ ത്രെഡുകളുടെ ഒരു ശൃംഖല നിലവിലുണ്ട്, അവിടെ ഓരോ ത്രെഡും ശൃംഖലയിലെ അടുത്ത ത്രെഡ് കൈവശം വെച്ചിരിക്കുന്ന ഒരു റിസോഴ്സിനായി കാത്തിരിക്കുന്നു.
ഡെഡ്ലോക്ക് തടയുന്നതിന് ഈ വ്യവസ്ഥകളിലൊന്നെങ്കിലും തകർക്കേണ്ടതുണ്ട്. ലോക്ക് ഏറ്റെടുക്കുന്നതിന് കർശനമായ ഒരു ഗ്ലോബൽ ഓർഡർ നടപ്പിലാക്കുക എന്നതാണ് ഏറ്റവും സാധാരണമായ തന്ത്രം.
ലിവെലോക്ക്
ഡെഡ്ലോക്കിന്റെ സൂക്ഷ്മമായ ബന്ധുവാണ് ലിവെലോക്ക്. ഒരു ലിവെലോക്കിൽ, ത്രെഡുകൾ തടഞ്ഞിട്ടില്ല - അവ സജീവമായി പ്രവർത്തിക്കുന്നു - എന്നാൽ അവർക്ക് മുന്നോട്ട് പോകാൻ കഴിയുന്നില്ല. ഉപയോഗപ്രദമായ ഒരു ജോലിയും ചെയ്യാതെ, പരസ്പരം അവസ്ഥാ മാറ്റങ്ങളോട് പ്രതികരിക്കുന്ന ഒരു ലൂപ്പിൽ അവർ കുടുങ്ങുന്നു.
ഇടുങ്ങിയ ഇടനാഴിയിൽ പരസ്പരം കടന്നുപോകാൻ ശ്രമിക്കുന്ന രണ്ട് ആളുകളാണ് ഇതിന് ക്ലാസിക് ഉദാഹരണം. അവർ രണ്ടുപേരും വിനയത്തോടെ ഇടത്തേക്ക് നീങ്ങാൻ ശ്രമിക്കുന്നു, എന്നാൽ അവർ പരസ്പരം തടയുന്നു. തുടർന്ന് അവർ രണ്ടുപേരും വലത്തേക്ക് നീങ്ങുന്നു, വീണ്ടും പരസ്പരം തടയുന്നു. അവർ സജീവമായി നീങ്ങുന്നു എന്നാൽ ഇടനാഴിയിൽ മുന്നോട്ട് പോകുന്നില്ല. സോഫ്റ്റ്വെയറിൽ, മോശമായി രൂപകൽപ്പന ചെയ്ത ഡെഡ്ലോക്ക് വീണ്ടെടുക്കൽ സംവിധാനങ്ങളുള്ളപ്പോൾ ഇത് സംഭവിക്കാം, അവിടെ ത്രെഡുകൾ വീണ്ടും പിന്നോട്ട് പോവുകയും വീണ്ടും ശ്രമിക്കുകയും ചെയ്യുന്നു, വീണ്ടും വൈരുദ്ധ്യമുണ്ടാക്കുന്നു.
ക്ഷാമം
ഒരു ത്രെഡിന് ആവശ്യമായ ഒരു റിസോഴ്സിലേക്ക് തുടർച്ചയായി പ്രവേശനം നിഷേധിക്കപ്പെടുമ്പോഴാണ് ക്ഷാമം സംഭവിക്കുന്നത്, റിസോഴ്സ് ലഭ്യമായാൽ പോലും. "നീതിയുക്തമല്ലാത്ത" ഷെഡ്യൂളിംഗ് അൽഗോരിതങ്ങൾ ഉള്ള സിസ്റ്റങ്ങളിൽ ഇത് സംഭവിക്കാം. ഉദാഹരണത്തിന്, ഒരു ലോക്കിംഗ് മെക്കാനിസം എല്ലായ്പ്പോഴും ഉയർന്ന മുൻഗണനയുള്ള ത്രെഡുകൾക്ക് ആക്സസ് നൽകുകയാണെങ്കിൽ, ഉയർന്ന മുൻഗണനയുള്ളവ നിരന്തരം ഉണ്ടായാൽ കുറഞ്ഞ മുൻഗണനയുള്ള ഒരു ത്രെഡിന് പ്രവർത്തിക്കാൻ അവസരം ലഭിക്കില്ല.
പ്രകടന അധികച്ചെലവ്
ലോക്കുകൾ സൗജന്യമല്ല. അവ നിരവധി രീതികളിൽ പ്രകടന അധികച്ചെലവ് അവതരിപ്പിക്കുന്നു:
- നേടാനുള്ള/റിലീസ് ചെയ്യാനുള്ള ചിലവ്: ഒരു ലോക്ക് നേടുന്നതിലും റിലീസ് ചെയ്യുന്നതിലും ആറ്റോമിക് പ്രവർത്തനങ്ങളും മെമ്മറി വേലികളും ഉൾപ്പെടുന്നു, ഇത് സാധാരണ നിർദ്ദേശങ്ങളേക്കാൾ കമ്പ്യൂട്ടേഷണൽപരമായി കൂടുതൽ ചെലവേറിയതാണ്.
- മത്സരം: ഒന്നിലധികം ത്രെഡുകൾ ഒരേ ലോക്കിനായി പതിവായി മത്സരിക്കുമ്പോൾ, സിസ്റ്റം ഉൽപാദനപരമായ ജോലി ചെയ്യുന്നതിനുപകരം സന്ദർഭം മാറുന്നതിനും ഷെഡ്യൂളിംഗ് ത്രെഡുകൾക്കുമായി വളരെയധികം സമയം ചെലവഴിക്കുന്നു. ഉയർന്ന മത്സരം ഫലപ്രദമായി എക്സിക്യൂഷൻ സീരിയലൈസ് ചെയ്യുന്നു, സമാന്തരതയുടെ ലക്ഷ്യം പരാജയപ്പെടുത്തുന്നു.
ലോക്ക്-അധിഷ്ഠിത സമന്വയത്തിനായുള്ള മികച്ച രീതികൾ
ലോക്കുകൾ ഉപയോഗിച്ച് ശരിയായതും കാര്യക്ഷമവുമായ കൺകറൻ്റ് കോഡ് എഴുതുന്നതിന് അച്ചടക്കവും മികച്ച രീതിയിലുള്ള പെരുമാറ്റവും ആവശ്യമാണ്. ഈ തത്വങ്ങൾ പ്രോഗ്രാമിംഗ് ഭാഷയോ പ്ലാറ്റ്ഫോമോ പരിഗണിക്കാതെ സാർവത്രികമായി ബാധകമാണ്.
1. ക്രിട്ടിക്കൽ സെക്ഷനുകൾ ചെറുതാക്കുക
ഏറ്റവും കുറഞ്ഞ സമയം ഒരു ലോക്ക് നിലനിർത്തണം. നിങ്ങളുടെ ക്രിട്ടിക്കൽ സെക്ഷനിൽ കൺകറൻ്റ് ആക്സസിൽ നിന്ന് പൂർണ്ണമായും പരിരക്ഷിക്കേണ്ട കോഡ് മാത്രമേ ഉണ്ടാകാവൂ. ഏതെങ്കിലും നിർണായകമല്ലാത്ത പ്രവർത്തനങ്ങൾ (I/O, പങ്കിട്ട അവസ്ഥയുമായി ബന്ധമില്ലാത്ത സങ്കീർണ്ണമായ കണക്കുകൂട്ടലുകൾ) ലോക്ക് ചെയ്ത ഭാഗത്തിന് പുറത്ത് ചെയ്യണം. നിങ്ങൾ എത്ര നേരം ഒരു ലോക്ക് കൈവശം വെക്കുന്നുവോ, അത്രത്തോളം മത്സരത്തിനുള്ള സാധ്യതയും മറ്റ് ത്രെഡുകൾ തടയുന്നതിനുള്ള സാധ്യതയും വർദ്ധിക്കുന്നു.
2. ശരിയായ ലോക്ക് ഗ്രാനുലാരിറ്റി തിരഞ്ഞെടുക്കുക
ലോക്ക് ഗ്രാനുലാരിറ്റി എന്നത് ഒരു ലോക്ക് പരിരക്ഷിക്കുന്ന ഡാറ്റയുടെ അളവിനെ സൂചിപ്പിക്കുന്നു.
- കോഴ്സ്-ഗ്രെയിൻഡ് ലോക്കിംഗ്: ഒരു വലിയ ഡാറ്റാ ഘടന അല്ലെങ്കിൽ ഒരു മുഴുവൻ ഉപസിസ്റ്റവും പരിരക്ഷിക്കാൻ ഒരൊറ്റ ലോക്ക് ഉപയോഗിക്കുന്നു. ഇത് നടപ്പിലാക്കാൻ ലളിതവും മനസ്സിലാക്കാൻ എളുപ്പവുമാണ്, എന്നാൽ ഡാറ്റയുടെ വ്യത്യസ്ത ഭാഗങ്ങളിലെ ബന്ധമില്ലാത്ത പ്രവർത്തനങ്ങളെല്ലാം ഒരേ ലോക്ക് ഉപയോഗിച്ച് സീരിയലൈസ് ചെയ്യുന്നതിനാൽ ഉയർന്ന മത്സരിതയിലേക്ക് ഇത് നയിച്ചേക്കാം.
- ഫൈൻ-ഗ്രെയിൻഡ് ലോക്കിംഗ്: ഒരു ഡാറ്റാ ഘടനയുടെ വ്യത്യസ്തവും, സ്വതന്ത്രവുമായ ഭാഗങ്ങൾ പരിരക്ഷിക്കാൻ ഒന്നിലധികം ലോക്കുകൾ ഉപയോഗിക്കുന്നു. ഉദാഹരണത്തിന്, ഒരു മുഴുവൻ ഹാഷ് ടേബിളിനും ഒരു ലോക്ക് ഉണ്ടാക്കുന്നതിനുപകരം, നിങ്ങൾക്ക് ഓരോ ബക്കറ്റിനും ഒരു പ്രത്യേക ലോക്ക് ഉണ്ടാകാം. ഇത് കൂടുതൽ സങ്കീർണ്ണമാണ്, എന്നാൽ കൂടുതൽ യഥാർത്ഥ സമാന്തരത അനുവദിക്കുന്നതിലൂടെ പ്രകടനം ഗണ്യമായി മെച്ചപ്പെടുത്താൻ കഴിയും.
അവയിലൊന്നിന്റെ തിരഞ്ഞെടുപ്പ് ലാളിത്യവും പ്രകടനവും തമ്മിലുള്ള ഒരു വിട്ടുവീഴ്ചയാണ്. പ്രകടന പ്രൊഫൈലിംഗ് ലോക്ക് മത്സരമാണ് ഒരു തടസ്സമെന്ന് കാണിക്കുകയാണെങ്കിൽ, കൂടുതൽ മികച്ച ലോക്കുകളിലേക്ക് നീങ്ങുക.
3. എല്ലായ്പ്പോഴും നിങ്ങളുടെ ലോക്കുകൾ റിലീസ് ചെയ്യുക
ഒരു ലോക്ക് റിലീസ് ചെയ്യാതിരിക്കുന്നത് നിങ്ങളുടെ സിസ്റ്റത്തെ സ്തംഭിപ്പിക്കുന്ന ഒരു വലിയ പിശകാണ്. ഒരു എക്സെപ്ഷനോ നേരത്തെയുള്ള റിട്ടേണോ ഒരു ക്രിട്ടിക്കൽ സെക്ഷനിൽ സംഭവിക്കുമ്പോഴാണ് ഈ പിശക് സാധാരണയായി സംഭവിക്കുന്നത്. ഇത് തടയുന്നതിന്, ജാവയിലോ സി# യിലോ try...finally ബ്ലോക്കുകളോ അല്ലെങ്കിൽ സി++-ൽ സ്കോപ്പ് ചെയ്ത ലോക്കുകളുള്ള RAII (Resource Acquisition Is Initialization) പാറ്റേണുകളോ പോലുള്ള ക്ലീനപ്പ് ഉറപ്പുനൽകുന്ന ഭാഷാ നിർമ്മിതികൾ എപ്പോഴും ഉപയോഗിക്കുക.
ഉദാഹരണം (try-finally ഉപയോഗിച്ച് സൂഡോ കോഡ്):
my_lock.acquire();
try {
// ഒരു എക്സെപ്ഷൻ എറിയാൻ സാധ്യതയുള്ള ക്രിട്ടിക്കൽ സെക്ഷൻ കോഡ്
} finally {
my_lock.release(); // ഇത് എക്സിക്യൂട്ട് ചെയ്യുമെന്ന് ഉറപ്പുനൽകുന്നു
}
4. കർശനമായ ലോക്ക് ഓർഡർ പിന്തുടരുക
ഡെഡ്ലോക്കുകൾ തടയുന്നതിന്, സർക്കുലർ വെയിറ്റ് അവസ്ഥ തകർക്കുക എന്നതാണ് ഏറ്റവും ഫലപ്രദമായ തന്ത്രം. ഒന്നിലധികം ലോക്കുകൾ നേടുന്നതിന് കർശനവും, ആഗോളപരവും, ഏകപക്ഷീയവുമായ ഒരു ഓർഡർ സ്ഥാപിക്കുക. ഒരു ത്രെഡിന് ലോക്ക് എ-യും ലോക്ക് ബി-യും കൈവശം വെക്കണമെങ്കിൽ, അത് എപ്പോഴും ലോക്ക് ബി നേടുന്നതിന് മുമ്പ് ലോക്ക് എ നേടണം. ഈ ലളിതമായ നിയമം സർക്കുലർ കാത്തിരിപ്പ് അസാധ്യമാക്കുന്നു.
5. ലോക്കിംഗിന് ബദലുകൾ പരിഗണിക്കുക
അടിസ്ഥാനപരമാണെങ്കിലും, കൺകറൻസി നിയന്ത്രണത്തിനുള്ള ഒരേയൊരു പരിഹാരമല്ല ലോക്കുകൾ. ഉയർന്ന പ്രകടനമുള്ള സിസ്റ്റങ്ങൾക്കായി, അത്യാധുനിക സാങ്കേതിക വിദ്യകൾ പര്യവേക്ഷണം ചെയ്യുന്നത് മൂല്യവത്താണ്:
- ലോക്ക്-ഫ്രീ ഡാറ്റാ ഘടനകൾ: ലോക്കുകൾ ഒട്ടും ഉപയോഗിക്കാതെ കൺകറൻ്റ് ആക്സസ് അനുവദിക്കുന്ന താഴ്ന്ന തലത്തിലുള്ള ആറ്റോമിക് ഹാർഡ്വെയർ നിർദ്ദേശങ്ങൾ (കമ്പയർ-ആൻഡ്-സ്വാപ്പ് പോലുള്ളവ) ഉപയോഗിച്ച് രൂപകൽപ്പന ചെയ്ത অত্যাധുനിക ഡാറ്റാ ഘടനകളാണ് ഇവ. ശരിയായി നടപ്പിലാക്കാൻ വളരെ ബുദ്ധിമുട്ടുള്ളവയാണെങ്കിലും ഉയർന്ന മത്സരത്തിൽ മികച്ച പ്രകടനം കാഴ്ചവെക്കാൻ കഴിയും.
- മാറാത്ത ഡാറ്റ: ഡാറ്റ ഉണ്ടാക്കിയ ശേഷം ഒരിക്കലും പരിഷ്കരിച്ചില്ലെങ്കിൽ, സമന്വയത്തിന്റെ ആവശ്യമില്ലാതെ തന്നെ ഇത് ത്രെഡുകൾക്കിടയിൽ സ്വതന്ത്രമായി പങ്കിടാൻ കഴിയും. ഇത് ഫങ്ഷണൽ പ്രോഗ്രാമിംഗിന്റെ ഒരു പ്രധാന തത്വമാണ്, കൂടാതെ കൺകറൻ്റ് ഡിസൈനുകൾ ലളിതമാക്കുന്നതിനുള്ള ഒരു ജനപ്രിയ മാർഗവുമാണ്.
- സോഫ്റ്റ്വെയർ ട്രാൻസാക്ഷണൽ മെമ്മറി (STM): ഡെവലപ്പർമാരെ മെമ്മറിയിൽ ആറ്റോമിക് ഇടപാടുകൾ നിർവചിക്കാൻ അനുവദിക്കുന്ന ഉയർന്ന തലത്തിലുള്ള ഒരു സംഗ്രഹമാണ് ഇത്, ഒരു ഡാറ്റാബേസിനു സമാനമാണ്. STM സിസ്റ്റം രഹസ്യമായി സങ്കീർണ്ണമായ സമന്വയ വിശദാംശങ്ങൾ കൈകാര്യം ചെയ്യുന്നു.
ഉപസംഹാരം
കൺകറൻ്റ് പ്രോഗ്രാമിംഗിന്റെ അടിസ്ഥാനശിലയാണ് ലോക്ക്-അധിഷ്ഠിത സമന്വയം. പങ്കിട്ട റിസോഴ്സുകൾ പരിരക്ഷിക്കുന്നതിനും ഡാറ്റാ കേടുപാടുകൾ തടയുന്നതിനും ഇത് ശക്തവും നേരിട്ടുള്ളതുമായ ഒരു മാർഗം നൽകുന്നു. ലളിതമായ മ്യൂട്ടെക്സ് മുതൽ കൂടുതൽ സൂക്ഷ്മമായ റീഡ്-റൈറ്റ് ലോക്ക് വരെ, ഈ പ്രിമിറ്റീവുകൾ മൾട്ടി-ത്രെഡ് ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്ന ഏതൊരു ഡെവലപ്പർക്കും അത്യാവശ്യമായ ഉപകരണങ്ങളാണ്.
എന്നിരുന്നാലും, ഈ ശക്തി ഉത്തരവാദിത്തം ആവശ്യപ്പെടുന്നു. ഡെഡ്ലോക്കുകൾ, ലിവെലോക്കുകൾ, പ്രകടനത്തകർച്ച തുടങ്ങിയ അപകടങ്ങളെക്കുറിച്ചുള്ള ആഴത്തിലുള്ള ധാരണ നിർബന്ധമാണ്. ക്രിട്ടിക്കൽ സെക്ഷൻ വലുപ്പം കുറയ്ക്കുക, ഉചിതമായ ലോക്ക് ഗ്രാനുലാരിറ്റി തിരഞ്ഞെടുക്കുക, കർശനമായ ലോക്ക് ഓർഡർ നടപ്പിലാക്കുക തുടങ്ങിയ മികച്ച രീതികൾ പാലിച്ച്, അതിന്റെ അപകടങ്ങൾ ഒഴിവാക്കുമ്പോൾ തന്നെ കൺകറൻസിയുടെ ശക്തി നിങ്ങൾക്ക് പ്രയോജനപ്പെടുത്താനാകും.
കൺകറൻസിയിൽ പ്രാവീണ്യം നേടുന്നത് ഒരു യാത്രയാണ്. ഇത് ശ്രദ്ധാപൂർവമായ രൂപകൽപ്പനയും, കർശനമായ പരിശോധനയും, ത്രെഡുകൾ സമാന്തരമായി പ്രവർത്തിക്കുമ്പോൾ ഉണ്ടാകാൻ സാധ്യതയുള്ള സങ്കീർണ്ണമായ ഇടപെടലുകളെക്കുറിച്ച് എപ്പോഴും ബോധവാന്മാരായിരിക്കേണ്ട ഒരു ചിന്താഗതിയും ആവശ്യമാണ്. ലോക്ക് ചെയ്യുന്നതിലെ കലയിൽ പ്രാവീണ്യം നേടുന്നതിലൂടെ, വേഗതയും പ്രതികരണശേഷിയുമുള്ളതും, എന്നാൽ ശക്തവും, വിശ്വസനീയവും, ശരിയായതുമായ സോഫ്റ്റ്വെയർ നിർമ്മിക്കുന്നതിനുള്ള ഒരു നിർണായക ചുവടുവെപ്പ് നിങ്ങൾ വെക്കുന്നു.