ධාවන තත්වයක් යනු කුමක්ද?


1010

බහුවිධ යෙදුම් ලිවීමේදී, අත්විඳින වඩාත් සුලභ ගැටළුවක් වන්නේ ධාවන තත්වයන් ය.

ප්‍රජාවට මගේ ප්‍රශ්න:

ධාවන තත්වය කුමක්ද?
ඔබ ඒවා හඳුනා ගන්නේ කෙසේද?
ඔබ ඒවා හසුරුවන්නේ කෙසේද?
අවසාන වශයෙන්, ඒවා ඇතිවීම වළක්වා ගන්නේ කෙසේද?


3
ලිනක්ස් HOWTO සඳහා වන ආරක්‍ෂිත ක්‍රමලේඛනයේ ඒවා මොනවාද සහ ඒවා වළක්වා ගන්නේ කෙසේද යන්න විස්තර කරන විශිෂ්ට පරිච්ඡේදයක් ඇත .
ක්‍රේග් එච්

4
භාෂාව සඳහන් නොකර - මෙම ප්‍රශ්නයේ බොහෝ කොටස් වලට නිසි ලෙස පිළිතුරු දිය නොහැකි බව මම සඳහන් කිරීමට කැමැත්තෙමි, මන්ද විවිධ භාෂාවලින් අර්ථ දැක්වීම, ප්‍රතිවිපාක සහ ඒවා වැළැක්වීමේ මෙවලම් එකිනෙකට වෙනස් විය හැකිය.
මයික්එම්බී

Ike මයික්එම්බී. රේස් කැචර් විසින් සිදු කරන ලද ආකාරයට බයිට් කේත ක්‍රියාත්මක කිරීම විශ්ලේෂණය කිරීමේදී හැර, එකඟ විය (මෙම නූල් stackoverflow.com/a/29361427/1363844 බලන්න ) අපට බයිට් කේතයට සම්පාදනය කරන භාෂා 62 ක් පමණ ආමන්ත්‍රණය කළ හැකිය (බලන්න en.wikipedia.org / wiki / List_of_JVM_languages )
බෙන්

Answers:


1277

ත්‍රෙඩ් දෙකකට හෝ වැඩි ගණනකට හවුල් දත්ත වලට ප්‍රවේශ විය හැකි අතර ඔවුන් එය එකවර වෙනස් කිරීමට උත්සාහ කරන විට ධාවන තත්වයක් ඇතිවේ. නූල් උපලේඛනගත කිරීමේ ඇල්ගොරිතම ඕනෑම වේලාවක නූල් අතර හුවමාරු විය හැකි බැවින්, හවුල් දත්ත වෙත ප්‍රවේශ වීමට නූල් උත්සාහ කරන අනුපිළිවෙල ඔබ නොදනී. එබැවින්, දත්ත වෙනස් කිරීමේ ප්‍රති result ලය නූල් උපලේඛනගත කිරීමේ ඇල්ගොරිතම මත රඳා පවතී, එනම් නූල් දෙකම දත්ත වලට ප්‍රවේශ වීමට / වෙනස් කිරීමට “ධාවන” වේ.

බොහෝ විට ගැටලු ඇති වන්නේ එක් නූල් එකක් "චෙක්-පසුව-ක්‍රියාව" කරන විට (උදා: අගය X නම් "පරීක්ෂා කරන්න", පසුව X අගය මත රඳා පවතින දෙයක් කිරීමට "ක්‍රියා කරන්න") සහ තවත් නූල් එකක් වටිනාකමට යමක් කරයි "පරීක්ෂා කිරීම" සහ "ක්‍රියාව" අතර. උදා:

if (x == 5) // The "Check"
{
   y = x * 2; // The "Act"

   // If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
   // y will not be equal to 10.
}

කාරණය නම්, y 10 විය හැකිය, නැතහොත් එය ඕනෑම දෙයක් විය හැකිය, වෙනත් නූල් චෙක්පත සහ ක්‍රියාව අතර x වෙනස් වී තිබේද යන්න මත පදනම්ව. ඔබට දැන ගැනීමේ සැබෑ ක්‍රමයක් නොමැත.

ධාවන තත්වයන් ඇතිවීම වැළැක්වීම සඳහා, වරකට එක් නූල් එකකට පමණක් දත්ත වලට ප්‍රවේශ විය හැකි බව සහතික කිරීම සඳහා ඔබ සාමාන්‍යයෙන් හවුල් දත්ත වටා අගුලක් තබනු ඇත. මෙය මෙවැනි දෙයක් අදහස් කරයි:

// Obtain lock for x
if (x == 5)
{
   y = x * 2; // Now, nothing can change x until the lock is released. 
              // Therefore y = 10
}
// release lock for x

125
අගුල හමු වූ විට අනෙක් නූල් කරන්නේ කුමක්ද? එය බලා සිටිනවාද? දෝෂයක් තිබේද?
බ්‍රයන් ඔර්ටිස්

180
ඔව්, අනෙක් නූල් ඉදිරියට යාමට පෙර අගුල මුදා හරින තෙක් බලා සිටීමට සිදුවනු ඇත. මෙමඟින් අගුල එය අවසන් වූ විට රඳවා තබා ගන්නා නූල් මඟින් මුදා හැරීම ඉතා වැදගත් වේ. එය කිසි විටෙකත් නිකුත් නොකරන්නේ නම්, අනෙක් නූල් දින නියමයක් නොමැතිව බලා සිටිනු ඇත.
ලෙහාන්

2
AnIan බහු තෙරපුම් පද්ධතියක සෑම විටම සම්පත් බෙදා ගැනීමට අවශ්‍ය අවස්ථා තිබේ. විකල්පයක් ලබා නොදී එක් ප්‍රවේශයක් නරක යැයි කීම .ලදායී නොවේ. මම සැමවිටම වැඩිදියුණු කිරීමට ක්‍රම සොයමින් සිටින අතර විකල්පයක් තිබේ නම් මම එය සතුටින් ගවේෂණය කර ගැති සහ අවාසි කිරා මැන බලමි.
ඩෙස්පර්ටාර්

2
Es ඩෙස්පර්ටාර් ... එසේම, සම්පත් සෑම විටම මිල්ටි-නූල් පද්ධතියක බෙදා ගැනීමට අවශ්‍ය වනු ඇත. උදාහරණයක් ලෙස ඔබට එක් එක් මූලද්‍රව්‍යයට සැකසුම් අවශ්‍ය වන අරාවක් තිබිය හැකිය. ඔබට සමහර විට අරාව කොටස් කර එක් එක් කොටස සඳහා නූල් එකක් තිබිය හැකි අතර නූල් වලට එකිනෙකාගෙන් සම්පූර්ණයෙන්ම ස්වාධීනව ඔවුන්ගේ කාර්යයන් කළ හැකිය.
ඉයන් වර්බර්ටන්

12
තරඟයක් සිදුවීමට නම්, එක් නූල් එකක් හවුල් දත්ත වෙනස් කිරීමට උත්සාහ කරන අතර අනෙක් නූල් වලට එය කියවීමට හෝ වෙනස් කිරීමට හැකිය.
SomeWittyUsername

216

හවුල් සම්පතකට ප්‍රවේශ විය හැකි බහු-ත්‍රෙඩ් (හෝ වෙනත් ආකාරයකින් සමාන්තර) කේතයක් අනපේක්ෂිත ප්‍රති .ල ගෙන දෙන අයුරින් කළ හැකි විට “ධාවන තත්වයක්” පවතී.

මෙම උදාහරණය ගන්න:

for ( int i = 0; i < 10000000; i++ )
{
   x = x + 1; 
}

ඔබට එකවර මෙම කේතය ක්‍රියාත්මක කරන නූල් 5 ක් තිබුනේ නම්, x හි වටිනාකම 50,000,000 ක් නොවේ. එය ඇත්ත වශයෙන්ම එක් එක් ධාවනය සමඟ වෙනස් වේ.

මෙයට හේතුව, එක් එක් නූල් x හි අගය වැඩි කිරීම සඳහා, ඔවුන් පහත සඳහන් දේ කළ යුතු බැවිනි: (සරල කරන ලද, පැහැදිලිවම)

X හි අගය ලබා ගන්න
මෙම අගයට 1 ක් එක් කරන්න
මෙම අගය x වෙත ගබඩා කරන්න

ඕනෑම නූලක් ඕනෑම වේලාවක මෙම ක්‍රියාවලියේ ඕනෑම පියවරක් විය හැකි අතර හවුල් සම්පතක් සම්බන්ධ වූ විට ඔවුනට එකිනෙකා මත පියවර තැබිය හැකිය. X කියවන කාලය තුළ සහ එය නැවත ලියන විට x හි තත්වය වෙනත් නූලකින් වෙනස් කළ හැකිය.

නූල් x හි අගය ලබා ගනී යැයි කියමු, නමුත් එය තවම ගබඩා කර නැත. තවත් නූල් එකකට x හි එකම අගය ලබා ගත හැකිය (මක්නිසාද යත් එය තවම වෙනස් කර නැති නිසා) එවිට ඔවුන් දෙදෙනාම එකම අගය (x + 1) x හි නැවත ගබඩා කරනු ඇත!

උදාහරණයක්:

නූල් 1: x කියවයි, අගය 7 කි
නූල් 1: x ට 1 එකතු කරන්න, අගය දැන් 8 කි
නූල් 2: x කියවයි, අගය 7 කි
නූල් 1: x හි 8 ගබඩා කරයි
නූල් 2: 1 සිට x දක්වා එකතු කරයි, අගය දැන් 8 කි
නූල් 2: x හි 8 ගබඩා කරයි

හවුල් සම්පතට ප්‍රවේශ වන කේතයට පෙර යම් ආකාරයක අගුලු දැමීමේ යාන්ත්‍රණයක් භාවිතා කිරීමෙන් ධාවන තත්වයන් වළක්වා ගත හැකිය :

for ( int i = 0; i < 10000000; i++ )
{
   //lock x
   x = x + 1; 
   //unlock x
}

මෙන්න, පිළිතුර සෑම අවස්ථාවකම 50,000,000 ක් ලෙස එළියට එයි.

අගුලු දැමීම පිළිබඳ වැඩි විස්තර සඳහා, සොයන්න: mutex, semaphore, විවේචනාත්මක අංශය, හවුල් සම්පත්.


එවැනි දේවල් නරක අතට හැරෙන්නේ කෙසේදැයි පරීක්ෂා කිරීමේ වැඩසටහනක උදාහරණයක් සඳහා jakob.engbloms.se/archives/65 බලන්න ... එය සැබවින්ම රඳා පවතින්නේ ඔබ ක්‍රියාත්මක වන යන්ත්‍රයේ මතක ආකෘතිය මත ය.
jakobengblom2

1
මිලියන 10 ට නතර කළ යුතු නම් එය මිලියන 50 දක්වා ලබා ගන්නේ කෙසේද?

9
omnocomprende: ස්නිපටයට කෙලින්ම විස්තර කර ඇති පරිදි වරකට එකම කේතය ක්‍රියාත්මක කරන නූල් 5 කින් ...
ජෝන් ස්කීට්

4
On ජෝන්ස්කීට් ඔබ හරි, මම අයි සහ එක්ස් ව්‍යාකූල කළා. ඔබට ස්තුතියි.

සිංගල්ටන් රටාව ක්‍රියාත්මක කිරීමේදී ද්විත්ව චෙක් අගුළු දැමීම ධාවන තත්ත්වය වැළැක්වීම සඳහා එවැනි උදාහරණයකි.
භාරත් දොඩෙජා

153

තරඟ කොන්දේසියක් යනු කුමක්ද?

ඔබ සවස 5 ට චිත්‍රපටයකට යාමට සැලසුම් කර ඇත. ඔබ සවස 4 ට ප්‍රවේශ පත්‍ර ලබා ගත හැකිදැයි විමසයි. නියෝජිතයා පවසන්නේ ඒවා ලබා ගත හැකි බවයි. ප්‍රදර්ශනයට මිනිත්තු 5 කට පෙර ඔබ විවේකීව ටිකට් කවුළුව වෙත ළඟා වේ. මට විශ්වාසයි ඔබට සිදුවන්නේ කුමක්දැයි අනුමාන කළ හැකිය: එය සම්පූර්ණ නිවසකි. මෙහි ගැටළුව වූයේ චෙක්පත සහ ක්‍රියාව අතර කාල සීමාවයි. ඔබ 4 ට විමසා 5 ට ක්‍රියා කළා. මේ අතරතුර, වෙනත් අයෙක් ටිකට්පත් උදුරා ගත්තා. එය ධාවන කොන්දේසියකි - විශේෂයෙන් තරඟ කොන්දේසි වල "පරීක්ෂා කිරීම-පසුව ක්‍රියා කිරීම".

ඔබ ඒවා හඳුනා ගන්නේ කෙසේද?

ආගමික කේත සමාලෝචනය, බහු නූල් ඒකක පරීක්ෂණ. කෙටිමඟක් නොමැත. මේ මත සූර්යග්‍රහණ ප්ලගීන කිහිපයක් මතුවෙමින් පවතී, නමුත් තවමත් ස්ථායී කිසිවක් නොමැත.

ඔබ ඒවා හසුරුවන්නේ කෙසේද?

හොඳම දෙය නම් අතුරු ආබාධ රහිත හා අස්ථායි ක්‍රියාකාරිත්වයන් නිර්මාණය කිරීම, හැකි තරම් වෙනස් කළ නොහැකි දෑ භාවිතා කිරීමයි. නමුත් එය සැමවිටම කළ නොහැකිය. එබැවින් java.util.concurrent.atomic, සමගාමී දත්ත ව්‍යුහයන්, නිසි සමමුහුර්තකරණය සහ නළු පාදක සමගාමී මුදල් භාවිතා කිරීම උපකාරී වේ.

සමගාමී මුදල් සඳහා හොඳම සම්පත JCIP ය. ඉහත පැහැදිලි කිරීම පිළිබඳ වැඩි විස්තර මෙතැනින් ලබා ගත හැකිය .


කේත සමාලෝචන සහ ඒකක පරීක්ෂණ ඔබේ කන් අතර ප්‍රවාහය ආකෘතිකරණය කිරීමට සහ හවුල් මතකය අඩුවෙන් භාවිතා කිරීමට ද්විතියික වේ.
Acumenus

2
ධාවන තත්වයක සැබෑ ලෝක උදාහරණය මම අගය කළෙමි
ටොම් ඕ.

11
පිළිතුර මාපට ඇඟිල්ල දිගු කරනවා වගේ . විසඳුම නම්: ඔබ ටිකට් පත් 4-5 අතර mutex සමඟ අගුළු දමයි (අන්යෝන්ය ව්‍යතිරේකය, c ++). සැබෑ ලෝකයේ එය ප්‍රවේශ පත්‍ර වෙන් කිරීම ලෙස හැඳින්වේ :)
වෝල්ට්

1
ඔබ ජාවා පමණක් බිටු අතහැර දැමුවහොත් එය හොඳ පිළිතුරක් වනු ඇත (ප්‍රශ්නය ජාවා ගැන නොව පොදුවේ ධාවන තත්වයන්යි)
කොරී ගෝල්ඩ්බර්ග්

මෙය ධාවන තත්වයක් නොවේ. "ව්‍යාපාර" දෘෂ්ටිකෝණයකින් ඔබ බොහෝ වේලාවක් බලා සිටියේය. නිසැකවම පසු ඇණවුම විසඳුමක් නොවේ.
ස්කැපර් යන්ත්‍රයක්

66

ධාවන තත්වයන් සහ දත්ත තරඟ අතර වැදගත් තාක්ෂණික වෙනසක් ඇත. බොහෝ පිළිතුරු මෙම නියමයන් සමාන යැයි උපකල්පනය කරන බවක් පෙනේ, නමුත් ඒවා එසේ නොවේ.

උපදෙස් 2 ක් එකම මතක ස්ථානයට ප්‍රවේශ වන විට දත්ත තරඟයක් සිදු වේ, අවම වශයෙන් මෙම ප්‍රවේශයන්ගෙන් එකක් වත් ලිවීමක් වන අතර මෙම ප්‍රවේශයන් අතර ඇණවුම් කිරීමට පෙර සිදු නොවේ . දැන් ඇණවුම් කිරීමට පෙර සිදුවන්නේ කුමක් ද යන්න බොහෝ විවාදයන්ට භාජනය වේ, නමුත් සාමාන්‍යයෙන් එකම අගුළු විචල්‍යයේ ඇති ulock-lock යුගල සහ එකම තත්ව විචල්‍යයේ රැඳී සිටින සං signal ා යුගල සිදුවීමට පෙර ඇණවුමක් ඇති කරයි.

ධාවන තත්වයක් යනු අර්ථකථන දෝෂයකි. එය වැරදි වැඩසටහන් හැසිරීමට තුඩු දෙන සිදුවීම් වේලාව හෝ අනුපිළිවෙලෙහි සිදුවන දෝෂයකි .

බොහෝ ධාවන තත්වයන් දත්ත ධාවන තරඟ නිසා විය හැකිය (ඇත්ත වශයෙන්ම), නමුත් මෙය අවශ්‍ය නොවේ. ඇත්ත වශයෙන්ම, දත්ත තරඟ සහ ධාවන තත්වයන් එකිනෙකාට අවශ්‍ය හෝ ප්‍රමාණවත් කොන්දේසියක් නොවේ. මෙම බ්ලොග් සටහන සරල බැංකු ගනුදෙනු උදාහරණයක් සමඟ වෙනස ඉතා හොඳින් පැහැදිලි කරයි. වෙනස පැහැදිලි කරන තවත් සරල උදාහරණයක් මෙන්න .

දැන් අපි පාරිභාෂිතය ඇණ ගසා ඇති හෙයින්, මුල් ප්‍රශ්නයට පිළිතුරු දීමට උත්සාහ කරමු.

ධාවන තත්වයන් අර්ථකථන දෝෂ බැවින්, ඒවා හඳුනා ගැනීමේ සාමාන්‍ය ක්‍රමයක් නොමැත. මෙයට හේතුව සාමාන්‍ය නඩුවේ නිවැරදි එදිරිව වැරදි වැඩසටහන් හැසිරීම වෙන්කර හඳුනාගත හැකි ස්වයංක්‍රීය ඔරකල් ක්‍රමයක් නොමැති වීමයි. ධාවන පථය හඳුනාගත නොහැකි ගැටළුවකි.

අනෙක් අතට, දත්ත ධාවන තරඟ සඳහා නිරවද්‍යතාවට නිශ්චිතවම සම්බන්ධ නොවන නිශ්චිත අර්ථ දැක්වීමක් ඇති අතර එබැවින් යමෙකුට ඒවා හඳුනාගත හැකිය. දත්ත ධාවන අනාවරකවල බොහෝ රසයන් ඇත (ස්ථිතික / ගතික දත්ත ධාවන අනාවරනය, ලොක්සෙට් මත පදනම් වූ දත්ත ධාවන අනාවරනය, සිදුවීමට පෙර-පදනම් වූ දත්ත ධාවන අනාවරනය, දෙමුහුන් දත්ත ධාවන අනාවරනය). නවීන ගතික දත්ත ධාවන අනාවරකයේ තත්වය වන්නේ ThreadSanitizer වන අතර එය ප්‍රායෝගිකව ඉතා හොඳින් ක්‍රියාත්මක වේ.

පොදුවේ දත්ත තරඟ හැසිරවීම සඳහා යම් දත්ත ක්‍රමලේඛ විනයක් අවශ්‍ය වේ - හවුල් දත්ත වලට ප්‍රවේශය අතර දාරවලට පෙර (සංවර්ධනයේදී හෝ ඉහත සඳහන් මෙවලම් භාවිතයෙන් ඒවා අනාවරණය වූ පසු). මෙය අගුල්, තත්ව විචල්‍යයන්, සෙමෆෝර් යනාදිය හරහා කළ හැකිය. කෙසේ වෙතත්, ඉදිකිරීම් මඟින් දත්ත ධාවන තරඟ වලක්වා ගත හැකි පණිවුඩ හුවමාරුව (හවුල් මතකය වෙනුවට) වැනි විවිධ ක්‍රමලේඛන උපමා භාවිතා කළ හැකිය.


තරඟයේ තත්වය අවබෝධ කර ගැනීම සඳහා වෙනස ඉතා වැදගත් වේ. ස්තූතියි!
ProgramCpp

"එය වැරදි වැඩසටහන් හැසිරීමට තුඩු දෙන සිදුවීම් වේලාව හෝ අනුපිළිවෙලෙහි සිදුවන දෝෂයකි." පරිපූර්ණ අර්ථ දැක්වීම! ඇත්ත වශයෙන්ම, යෙදුමක එක් අවස්ථාවක් තුළ සිදුවීම් සිදුවිය යුතු යැයි උපකල්පනය කිරීමට හේතුවක් නැත. අවස්ථා කිහිපයක්ම අදාළ වේ.
truefusion

37

කැනොනිකල් අර්ථ දැක්වීමක් යනු " නූල් දෙකක් එකම වේලාවක මතකයේ එකම ස්ථානයට ප්‍රවේශ වන විට සහ අවම වශයෙන් එක් ප්‍රවේශයක් ලිවීමකි ." තත්වය තුළ "පා er කයා" නූල් පැරණි අගය හෝ නව අගය ලබා ගත හැකිය, කුමන නූල් "තරඟය ජය ගනීද" යන්න මත පදනම්ව. මෙය සැමවිටම දෝෂයක් නොවේ. ඇත්ත වශයෙන්ම සමහර කෙස් කළඹේ පහළ මට්ටමේ ඇල්ගොරිතම මෙය කරන්නේ අරමුණක් ඇතුවයි - නමුත් එය සාමාන්‍යයෙන් වළක්වා ගත යුතුය. St ස්ටීව් ගුරි දෙන්න එය ගැටලුවක් විය හැකි බවට හොඳ උදාහරණයක්.


3
ධාවන තත්වයන් ප්‍රයෝජනවත් වන්නේ කෙසේද යන්න පිළිබඳ උදාහරණයක් ඔබට ලබා දිය හැකිද? ගූග්ලිං උදව් කළේ නැත.
ඇලෙක්ස් වී.

3
Lex ඇලෙක්ස් වී. මේ අවස්ථාවේදී, මා කතා කළේ කුමක් දැයි මා දන්නේ නැත. මම සිතන්නේ මෙය අගුළු රහිත ක්‍රමලේඛනය සඳහා යොමු කිරීමක් විය හැකි නමුත් එය ඇත්ත වශයෙන්ම නිවැරදි නොවන අතර එය ධාවන තත්වයන් මත රඳා පවතී.
ක්‍රිස් කොන්වේ

34

ධාවන තත්වයක් යනු යම් ආකාරයක දෝෂයකි, එය සිදුවන්නේ යම් යම් තාවකාලික කොන්දේසි සමඟ පමණි.

උදාහරණය: ඔබට A සහ ​​B යන නූල් දෙකක් ඇතැයි සිතන්න.

නූල් A හි:

if( object.a != 0 )
    object.avg = total / object.a

නූල් බී හි:

object.a = 0

එම වස්තුව පරීක්ෂා කිරීමෙන් පසුව A නූල් පූර්ව නිගමනය කර ඇත්නම්, එය ශුන්‍ය නොවේ, B විසින් සිදු කරනු ඇති අතර a = 0, A නූල් සකසනය ලබා ගත් විට, එය “ශුන්‍යයෙන් බෙදීම” කරයි.

මෙම දෝෂය සිදුවන්නේ if ප්‍රකාශයෙන් පසුව A නූල් පූර්ව නිගමනය කළ විට පමණි, එය ඉතා දුර්ලභ ය, නමුත් එය සිදුවිය හැකිය.


21

ධාවන තත්ත්වය මෘදුකාංග සමඟ පමණක් නොව දෘඩාංග සමඟ ද සම්බන්ධ වේ. ඇත්ත වශයෙන්ම මෙම යෙදුම මුලින් නිර්මාණය කළේ දෘඩාංග කර්මාන්තය විසිනි.

විකිපීඩියාවට අනුව :

යන අදහස සමඟ බිහි වූ කාලීන එකිනෙකා ධාවන සංඥා දෙකක් සඳහා පළමු ප්රතිදානය බලපෑම් .

තාර්කික පරිපථයක ධාවන තත්වය:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

මෘදුකාංග කර්මාන්තය මෙම පදය වෙනස් කිරීමකින් තොරව ගෙන ඇති අතර එය තේරුම් ගැනීමට ටිකක් අපහසු වේ.

එය මෘදුකාංග ලෝකයට සිතියම් ගත කිරීම සඳහා ඔබ යම් ආදේශනයක් කළ යුතුය:

  • "සං als ා දෙකක්" => "නූල් දෙකක්" / "ක්‍රියාවලි දෙකක්"
  • "ප්‍රතිදානයට බලපෑම් කරන්න" => "හවුල් තත්වයකට බලපෑම් කරන්න"

එබැවින් මෘදුකාංග කර්මාන්තයේ ධාවන තත්වය යන්නෙන් අදහස් කරන්නේ “යම් හවුල් රාජ්‍යයකට බලපෑම් කිරීම” සඳහා “නූල් දෙකක්” / “ක්‍රියාවලි දෙකක්” එකිනෙකා අතරට දිවෙන අතර, හවුල් රාජ්‍යයේ අවසාන ප්‍රති result ලය යම් සියුම් කාල වෙනසක් මත රඳා පවතී. නූල් / ක්‍රියාවලි දියත් කිරීමේ අනුපිළිවෙල, නූල් / ක්‍රියාවලි උපලේඛන ආදිය.


21

තරඟ කොන්දේසියක් යනු සම්පතක් සඳහා සමගාමී නූල් හෝ ක්‍රියාවලි දෙකක් තරඟ කරන සමගාමී වැඩසටහන්කරණයේ තත්වයකි.


ඉතා පැහැදිලි පැහැදිලි කිරීමක්
gokareless

අවසාන තත්වය කුමක්ද?
රෝමන් ඇලෙක්සැන්ඩ්‍රොවිච්

1
Oman රෝමන් ඇලෙක්සැන්ඩ්‍රොවිච් වැඩසටහනේ අවසාන තත්වය. රාජ්යයන් විචල්යයන්ගේ අගයන් වැනි දේ ගැන සඳහන් කරයි. ලෙහාන්ගේ විශිෂ්ට පිළිතුර බලන්න. ඔහුගේ උදාහරණයේ ඇති “තත්වය” යන්නෙන් 'x' සහ 'y' හි අවසාන අගයන් දැක්වේ.
AMTerp

19

බහු-නූල් යෙදුම් හෝ බහු ක්‍රියාවලි පද්ධති වල ධාවන තත්වයන් ඇතිවේ. ධාවන තත්වයක්, එහි මූලික වශයෙන්, එකම නූලක හෝ ක්‍රියාවලියක නොවන කරුණු දෙකක් නිශ්චිත අනුපිළිවෙලකට සිදුවනු ඇතැයි උපකල්පනය කරන ඕනෑම දෙයක්, ඒවා සහතික කිරීමට පියවර නොගෙන. මෙය සාමාන්‍යයෙන් සිදුවන්නේ පන්තියක සාමාජික විචල්‍යයන් සැකසීමෙන් හා පරීක්ෂා කිරීමෙන් නූල් දෙකක් පණිවිඩ යවන විට දෙදෙනාම ප්‍රවේශ විය හැකිය. කර්තව්‍යයක් නිම කිරීමට තවත් නූල් කාලයක් ලබා දීම සඳහා එක් නූල් නින්දක් ඉල්ලා සිටින විට සෑම විටම පාහේ ධාවන තත්වයක් පවතී (එම නින්ද ලූපයක නොමැති නම්, යම් පිරික්සුම් යාන්ත්‍රණයක් සහිතව).

ධාවන තත්වයන් වලක්වා ගැනීමේ මෙවලම් භාෂාව සහ මෙහෙයුම් පද්ධතිය මත රඳා පවතී, නමුත් සමහර පොදු ඒවා වන්නේ මුටෙක්ස්, විවේචනාත්මක කොටස් සහ සං als ා ය. ඔබ පමණක් යමක් කරන බව තහවුරු කර ගැනීමට අවශ්‍ය විට Mutexes හොඳයි. වෙනත් අයෙකු යමක් කර අවසන් බව තහවුරු කර ගැනීමට ඔබට අවශ්‍ය විට සං als ා හොඳයි. හවුල් සම්පත් අවම කිරීමෙන් අනපේක්ෂිත හැසිරීම් වලක්වා ගත හැකිය

තරඟ තත්වයන් හඳුනා ගැනීම දුෂ්කර විය හැකි නමුත් සං signs ා කිහිපයක් තිබේ. නින්ද මත දැඩි ලෙස රඳා පවතින කේතය ජාතියේ තත්වයන්ට ගොදුරු වේ, එබැවින් පළමුව බලපෑමට ලක්වූ කේතයේ නිදා ගැනීමට ඇමතුම් සඳහා පරීක්ෂා කරන්න. යම් යම් සිදුවීම් අනුපිළිවෙලක් උත්සාහ කිරීමට සහ බල කිරීමට නිදොස් කිරීම සඳහා විශේෂයෙන් දිගු නින්ද එකතු කිරීම ද භාවිතා කළ හැකිය. හැසිරීම ප්‍රතිනිෂ්පාදනය කිරීමට, දේවල් වල වේලාව වෙනස් කිරීමෙන් ඔබට එය අතුරුදහන් කළ හැකිදැයි බැලීමට සහ විසඳුම් සකස් කිරීමට මෙය ප්‍රයෝජනවත් වේ. නිදොස් කිරීම නිදොස් කිරීමෙන් පසු ඉවත් කළ යුතුය.

යමෙකුට ධාවන තත්වයක් ඇති බවට අත්සන් සං sign ාව නම්, සමහර යන්ත්‍රවල වරින් වර සිදුවන ගැටළුවක් තිබේ නම්. පොදු දෝෂ වනුයේ බිඳ වැටීම් සහ අවහිර කිරීම් ය. ල ging ු-සටහන් සමඟ, ඔබට බලපෑමට ලක් වූ ප්‍රදේශය සොයා ගැනීමට හැකි විය යුතු අතර එතැන් සිට නැවත වැඩ කරන්න.


12

මයික්‍රොසොෆ්ට් ඇත්ත වශයෙන්ම මෙම තරඟ තත්වයන් සහ අවහිරතා පිළිබඳ සවිස්තරාත්මක ලිපියක් ප්‍රකාශයට පත් කර ඇත . එයින් වඩාත්ම සාරාංශගත සාරාංශය වනුයේ මාතෘකාව ඡේදය:

ත්‍රෙඩ් දෙකක් එකවර හවුල් විචල්‍යයකට ප්‍රවේශ වන විට ධාවන තත්වයක් ඇතිවේ. පළමු නූල් විචල්යය කියවන අතර දෙවන නූල් විචල්යයෙන් එකම අගය කියවයි. පළමු නූල් සහ දෙවන නූල් වල අගය මත ඔවුන්ගේ ක්‍රියාකාරිත්වය සිදු කරන අතර, හවුල් විචල්‍යයට අවසාන වශයෙන් අගය ලිවිය හැක්කේ කුමන නූල් දැයි බැලීමට ඔවුහු පෙළඹෙති. නූල් වල වටිනාකම අවසන් වරට ලියන අගය සංරක්ෂණය කර ඇත, මන්ද නූල් ලියන්නේ පෙර නූල් ලියා ඇති වටිනාකමට වඩා ය.


6

ධාවන තත්වයක් යනු කුමක්ද?

ක්‍රියාවලිය අනෙකුත් සිදුවීම්වල අනුක්‍රමය හෝ වේලාව මත විවේචනාත්මකව රඳා පවතින අවස්ථාව.

උදාහරණයක් ලෙස, ප්‍රොසෙසර් ඒ සහ ප්‍රොසෙසර් බී යන දෙකටම ඒවා ක්‍රියාත්මක කිරීම සඳහා සමාන සම්පත් අවශ්‍ය වේ.

ඔබ ඒවා හඳුනා ගන්නේ කෙසේද?

ධාවන තත්වය ස්වයංක්‍රීයව හඳුනා ගැනීමට මෙවලම් තිබේ:

ඔබ ඒවා හසුරුවන්නේ කෙසේද?

ධාවන තත්වය Mutex හෝ Semaphores මගින් හැසිරවිය හැකිය . ඒවා අගුලක් ලෙස ක්‍රියා කරන අතර ධාවන තත්වයන් වැළැක්වීම සඳහා යම් යම් අවශ්‍යතා මත පදනම්ව සම්පතක් ලබා ගැනීමට ක්‍රියාවලියකට ඉඩ ලබා දේ.

ඒවා ඇතිවීම වළක්වා ගන්නේ කෙසේද?

විවේචනාත්මක අංශ මග හැරීම වැනි ධාවන තත්ත්වය වැළැක්වීම සඳහා විවිධ ක්‍රම තිබේ .

  1. ඒවායේ තීරණාත්මක කලාප තුළ එකවර ක්‍රියාවලි දෙකක් නොමැත. ( අන්යෝන්ය බැහැර කිරීම)
  2. වේගය හෝ CPU ගණන ගැන කිසිදු උපකල්පනයක් සිදු නොකෙරේ.
  3. වෙනත් ක්‍රියාදාමයන් අවහිර කරන එහි තීරණාත්මක කලාපයෙන් පිටත කිසිදු ක්‍රියාවලියක් ක්‍රියාත්මක නොවේ.
  4. කිසිදු ක්‍රියාවලියක් එහි තීරණාත්මක කලාපයට ඇතුළු වීමට සදහටම බලා සිටිය යුතු නැත. (බී සම්පත් සඳහා බලා සිටීම, බී සම්පත් සඳහා බී බලා සිටීම, සී සම්පත් සඳහා බලා සිටීම)

2

ධාවන තත්වයක් යනු උපාංගයක් හෝ පද්ධතියක් එකවර මෙහෙයුම් දෙකක් හෝ වැඩි ගණනක් සිදු කිරීමට උත්සාහ කරන විට සිදුවන නුසුදුසු තත්වයකි, නමුත් උපාංගයේ හෝ පද්ධතියේ ස්වභාවය නිසා, මෙහෙයුම් නිසි අනුපිළිවෙලින් සිදු කළ යුතුය. නිවැරදිව සිදු කර ඇත.

පරිගණක මතකයේ හෝ ගබඩාවේදී, විශාල දත්ත ප්‍රමාණයක් කියවීමට හා ලිවීමට විධානයන් එකවරම ලැබුනහොත් ධාවන තත්වයක් ඇතිවිය හැකි අතර, පැරණි දත්ත තවමත් පවතින අතරතුර යන්ත්‍රය පැරණි දත්ත කිහිපයක් හෝ සියල්ල නැවත ලිවීමට උත්සාහ කරයි. කියවන්න. ප්‍රති result ලය පහත සඳහන් එකක් හෝ වැඩි ගණනක් විය හැකිය: පරිගණක බිඳවැටීමක්, “නීති විරෝධී ක්‍රියාවක්”, වැඩසටහන දැනුම්දීම සහ වසා දැමීම, පැරණි දත්ත කියවීමේ දෝෂ හෝ නව දත්ත ලිවීමේ දෝෂ.


1

ජාවා හි නූල් පහසුවෙන් තේරුම් ගැනීමට නවකයන්ට උපකාර වන සම්භාව්‍ය බැංකු ගිණුම් ශේෂ උදාහරණය මෙන්න:

public class BankAccount {

/**
 * @param args
 */
int accountNumber;
double accountBalance;

public synchronized boolean Deposit(double amount){
    double newAccountBalance=0;
    if(amount<=0){
        return false;
    }
    else {
        newAccountBalance = accountBalance+amount;
        accountBalance=newAccountBalance;
        return true;
    }

}
public synchronized boolean Withdraw(double amount){
    double newAccountBalance=0;
    if(amount>accountBalance){
        return false;
    }
    else{
        newAccountBalance = accountBalance-amount;
        accountBalance=newAccountBalance;
        return true;
    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    BankAccount b = new BankAccount();
    b.accountBalance=2000;
    System.out.println(b.Withdraw(3000));

}

තැන්පතු ක්‍රමයේදී negative ණ අගයක් තිබේ නම්, මිනිසුන්ට නිවැරදිව තැන්පත් කළ හැකිය
පාර්තසරතී බී

1

ඔබ "පරමාණුක" පන්ති භාවිතා කරන්නේ නම්, ඔබට ධාවන තත්වය වළක්වා ගත හැකිය . හේතුව, ත්‍රෙඩ් එකෙන් මෙහෙයුම් ලබාගෙන සැකසීම වෙන් නොකරන්න, උදාහරණය පහතින්:

AtomicInteger ai = new AtomicInteger(2);
ai.getAndAdd(5);

ප්රති result ලයක් වශයෙන්, ඔබට "ai" සබැඳිය 7 ක් ඇත. ඔබ ක්‍රියා දෙකක් කළද, දෙකම ක්‍රියාන්විතය එකම නූලක් සනාථ කරන අතර වෙනත් කිසිදු නූලක් මෙයට බාධා නොකරනු ඇත, එයින් අදහස් වන්නේ තරඟ කොන්දේසි නොමැති බවයි!


0

ජාතියේ තත්වය වඩා හොඳින් අවබෝධ කර ගැනීම සඳහා මෙම මූලික උදාහරණය උත්සාහ කරන්න:

    public class ThreadRaceCondition {

    /**
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Account myAccount = new Account(22222222);

        // Expected deposit: 250
        for (int i = 0; i < 50; i++) {
            Transaction t = new Transaction(myAccount,
                    Transaction.TransactionType.DEPOSIT, 5.00);
            t.start();
        }

        // Expected withdrawal: 50
        for (int i = 0; i < 50; i++) {
            Transaction t = new Transaction(myAccount,
                    Transaction.TransactionType.WITHDRAW, 1.00);
            t.start();

        }

        // Temporary sleep to ensure all threads are completed. Don't use in
        // realworld :-)
        Thread.sleep(1000);
        // Expected account balance is 200
        System.out.println("Final Account Balance: "
                + myAccount.getAccountBalance());

    }

}

class Transaction extends Thread {

    public static enum TransactionType {
        DEPOSIT(1), WITHDRAW(2);

        private int value;

        private TransactionType(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    };

    private TransactionType transactionType;
    private Account account;
    private double amount;

    /*
     * If transactionType == 1, deposit else if transactionType == 2 withdraw
     */
    public Transaction(Account account, TransactionType transactionType,
            double amount) {
        this.transactionType = transactionType;
        this.account = account;
        this.amount = amount;
    }

    public void run() {
        switch (this.transactionType) {
        case DEPOSIT:
            deposit();
            printBalance();
            break;
        case WITHDRAW:
            withdraw();
            printBalance();
            break;
        default:
            System.out.println("NOT A VALID TRANSACTION");
        }
        ;
    }

    public void deposit() {
        this.account.deposit(this.amount);
    }

    public void withdraw() {
        this.account.withdraw(amount);
    }

    public void printBalance() {
        System.out.println(Thread.currentThread().getName()
                + " : TransactionType: " + this.transactionType + ", Amount: "
                + this.amount);
        System.out.println("Account Balance: "
                + this.account.getAccountBalance());
    }
}

class Account {
    private int accountNumber;
    private double accountBalance;

    public int getAccountNumber() {
        return accountNumber;
    }

    public double getAccountBalance() {
        return accountBalance;
    }

    public Account(int accountNumber) {
        this.accountNumber = accountNumber;
    }

    // If this method is not synchronized, you will see race condition on
    // Remove syncronized keyword to see race condition
    public synchronized boolean deposit(double amount) {
        if (amount < 0) {
            return false;
        } else {
            accountBalance = accountBalance + amount;
            return true;
        }
    }

    // If this method is not synchronized, you will see race condition on
    // Remove syncronized keyword to see race condition
    public synchronized boolean withdraw(double amount) {
        if (amount > accountBalance) {
            return false;
        } else {
            accountBalance = accountBalance - amount;
            return true;
        }
    }
}

0

ඔබට සැමවිටම ධාවන තත්වයක් ඉවත දැමීමට අවශ්‍ය නැත. ඔබට ධජයක් තිබේ නම් එය කියවීමට හා ලිවීමට හැකි නම්, මෙම ධජය එක් නූල් එකකින් 'සිදු' කර ඇති අතර එමඟින් ධජය 'ඉවරයි' ලෙස සකසා ඇති විට අනෙක් නූල් සැකසීම නවත්වනු ඇත, ඔබට එම "තරඟය අවශ්‍ය නොවේ කොන්දේසිය "ඉවත් කිරීමට. ඇත්ත වශයෙන්ම, මෙය අශෝභන ධාවන තත්වයක් ලෙස හැඳින්විය හැකිය.

කෙසේ වෙතත්, ධාවන තත්වය හඳුනා ගැනීම සඳහා මෙවලමක් භාවිතා කිරීමෙන් එය හානිකර ධාවන තත්වයක් ලෙස හඳුනා ගනු ඇත.

ධාවන තත්වය පිළිබඳ වැඩි විස්තර මෙතැනින්, http://msdn.microsoft.com/en-us/magazine/cc546569.aspx .


ඔබේ පිළිතුර පදනම් වී ඇත්තේ කුමන භාෂාවද?
මයික්එම්බී

අවංකව කියනවා එය ඔබ ජාතිය කොන්දේසි තියෙනවා නම් කියලා මට තේරෙනවා ගත් විට , ඔබ තදින් පාලනය ආකාරයට ඔබගේ කේතය architecting නැත. එය ඔබේ න්‍යායාත්මක කාරණයේ ගැටලුවක් නොවිය හැකි අතර, ඔබ මෘදුකාංග නිර්මාණය හා සංවර්ධනය කරන ආකාරය පිළිබඳ විශාල ගැටළු සඳහා සාක්ෂි වේ. ඉක්මනින් හෝ පසුව වේදනාකාරී ධාවන තත්ව දෝෂ වලට මුහුණ දීමට බලාපොරොත්තු වන්න.
ඉංජිනේරු

0

ගණනය වැඩි වූ විගසම ගණනය කළ යුතු මෙහෙයුමක් සලකා බලන්න. එනම්, CounterThread අගය වැඩි කළ වහාම DisplayThread අගය මෑතකදී යාවත්කාලීන කළ අගය පෙන්වීමට අවශ්‍ය වේ.

int i = 0;

ප්‍රතිදානය

CounterThread -> i = 1  
DisplayThread -> i = 1  
CounterThread -> i = 2  
CounterThread -> i = 3  
CounterThread -> i = 4  
DisplayThread -> i = 4

මෙහිදී CounterThread නිතරම අගුල ලබා ගන්නා අතර DisplayThread දර්ශනය වීමට පෙර එහි අගය යාවත්කාලීන කරයි. මෙන්න ධාවන තත්වයක් පවතී. සමමුහුර්තකරණය භාවිතා කිරීමෙන් ධාවන තත්වය විසඳිය හැකිය


0

ධාවන තත්වයක් යනු නුසුදුසු තත්වයක් වන අතර එමඟින් ක්‍රියාවලියක් දෙකකට හෝ වැඩි ගණනකට එකවර බෙදාගත් දත්ත වලට ප්‍රවේශ විය හැකි හා වෙනස් කළ හැකිය. එය සිදු වූයේ සම්පතකට පරස්පර ප්‍රවේශයන් තිබූ බැවිනි. විවේචනාත්මක අංශයේ ගැටළුව ධාවන තත්වයට හේතු විය හැක. ක්‍රියාවලිය අතර තීරණාත්මක තත්ත්වය විසඳීම සඳහා අප විසින් වරකට එක් ක්‍රියාවලියක් පමණක් සිදු කර ඇති අතර එය තීරණාත්මක කොටස ක්‍රියාත්මක කරයි.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.