рд╕реА ++ рдореЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд▓рд╕реА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реВрддреНрд░

рд░реЗрдордВрдб рдЪреЗрди рдиреЗ рд▓реЙрдХрд▓реЗрд╕ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯреЛрдВ рдХреА рдПрдХ рдордиреЛрд░рдВрдЬрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд▓рд┐рдЦреАред рдореИрдВ рдЗрди рдиреЛрдЯреЛрдВ рдХреЛ рд╣реИрдмреНрд░реЗрдХреНрдЯрд┐рдХрдо рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдпрд╣ рдкреЛрд╕реНрдЯ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рдПрдХ рдкрд░рд┐рдЪрдп рд╣реИ, рдЬреЛ рдЪреЗрди рдХреЗ рддреАрди рдкреБрд░рд╛рдиреЗ рдкрджреЛрдВ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рд╣реИред
  1. C ++ рдмрд┐рд▓реНрдЯ-рдЗрди рдХреЗ рд╕рд╛рде рдЖрд▓рд╕реА рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди
  2. рд▓реЙрдХрд▓реЗрд╕ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди
  3. рд▓реЙрдХрд▓реЗрд╕ рдереНрд░реЗрдб-рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд▓рд╕реА рдЖрд░рдВрднреАрдХрд░рдг


C ++ рдмрд┐рд▓реНрдЯ-рдЗрди рдХреЗ рд╕рд╛рде рдЖрд▓рд╕реА рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди


C ++ рдореЗрдВ рд╕реНрдереИрддрд┐рдХ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХрд╛ рдкреНрд░рд╛рд░рдВрдн рдереНрд░реЗрдб рд╕реБрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЬрд╛рдирдмреВрдЭрдХрд░!

рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рдиреЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдХрд┐ рд╕реНрдереИрддрд┐рдХ рд╕реНрдерд╛рдиреАрдп рдЪрд░ (рд╡реИрд╢реНрд╡рд┐рдХ рд╡рд┐рд░реЛрдз рдХреЗ рдЕрдиреБрд╕рд╛рд░) рдХреЛ рдкрд╣рд▓реА рдмрд╛рд░ рдХреЛрдб рдмреНрд▓реЙрдХ рдХреЛ рдЖрд░рдореНрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдХреЛрдб рдЯреБрдХрдбрд╝реЗ рдореЗрдВ рдЙрдбрд╝рд╛рди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реНрд╡рдпрдВ рдЦреЛрдЬрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ рдЬреЛ рдкрд╣рд▓реЗ рдХреЙрд▓ рдкрд░ рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди "рд▓реЗрдЬрд╝реАрд▓реА" рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдмрд╛рдж рдХреЗ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИред

int ComputeSomething()
{
static int cachedResult = ComputeSomethingSlowly();
return cachedResult;
}

(рд▓реЛрдХрдкреНрд░рд┐рдп рд╕реА ++ рдПрдлрдПрдХреНрдпреВ рдореЗрдВ рд▓рдЧрднрдЧ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдХреА рд╕рд▓рд╛рд╣ рджреА рдЬрд╛рддреА рд╣реИ, рддрд╛рдХрд┐ рд╡реИрд╢реНрд╡рд┐рдХ рд╕реНрдереИрддрд┐рдХ рдЪрд░ рдХреЗ рдЖрд░рдВрдн рдХреЗ рд╕рдВрдХрд▓рдХ рдХреЗ рдЖрджреЗрд╢ рдкрд░ рдирд┐рд░реНрднрд░ рди рд╣реЛред)

рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрдХрд▓рдХ рд╕реНрдереИрддрд┐рдХ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХреЗ рдЖрд░рдВрднреАрдХрд░рдг рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ:
int ComputeSomething()
{
static bool cachedResult_computed = false;
static int cachedResult;
if (!cachedResult_computed) {
cachedResult_computed = true;
cachedResult = ComputeSomethingSlowly();
}

return cachedResult;
}

рдЕрдм рдПрдпрд░ рдХрдВрдбреАрд╢рдирд┐рдВрдЧ рдирдЧреНрди рдЖрдВрдЦреЛрдВ рдХреЛ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИред рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ ComputeSomething() рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рджреЛ рдереНрд░реЗрдбреНрд╕ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВред рдкрд╣рд▓реЗ рдзрд╛рдЧреЗ рдореЗрдВ рдХреЗрд╡рд▓ cachedResult_computed = true рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ cachedResult_computed = true рджреВрд╕рд░реЗ рдереНрд░реЗрдб рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ cachedResult_computed = true ред рдЕрдм рджреВрд╕рд░рд╛ рдереНрд░реЗрдб cachedResult_computed рдлреНрд▓реИрдЧ cachedResult_computed рджреЗрдЦрддрд╛ рд╣реИ, рд╡реИрд░рд┐рдПрдмрд▓ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреА рдЕрдирдЗрдВрд╕реНрдЯрд╛рд▓реНрдб рд╡реИрд▓реНрдпреВ рд▓реЗрддрд╛ рд╣реИред

рдФрд░ рдпрд╣ рд╕рдВрдХрд▓рдХ рдореЗрдВ рдмрдЧ рдирд╣реАрдВ рд╣реИ - рдпрд╣ рд╕реА ++ рдорд╛рдирдХ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред (рддрдм, TC1 рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ, рдереНрд░реЗрдб рд╕реБрд░рдХреНрд╖рд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬреЛ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдП рдЬрд╛рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ "рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░" рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред)

рд╕реНрдереИрддрд┐рдХ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХреЗ рдмрд╣реБрдкрд░рдд рдЖрд░рдВрднрд┐рдХрдХрд░рдг рд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ:

class Something { ... };
int ComputeSomething()
{
static Something s;
return s.ComputeIt();
}

рдРрд╕рд╛ рдХреЛрдб рд╕рд╛рдордиреЗ рдЖрдПрдЧрд╛

class Something { ... };
int ComputeSomething()
{
static bool s_constructed = false;
static uninitialized Something s;
if (!s_constructed) {
s_constructed = true;
new(&s) Something; // s
atexit(DestructS);
}

return s.ComputeIt();
}
// s
void DestructS()
{
ComputeSomething::s.~Something();
}


рдЕрдм рдХрдИ рд╕рдВрднрд╛рд╡рд┐рдд рдПрдпрд░ рдХрдВрдбреАрд╢рдирд┐рдВрдЧ рд╣реИрдВред рдкрд╣рд▓реЗ рдХреА рддрд░рд╣, рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рд╕реЗ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдЖрдЧреЗ рдирд┐рдХрд▓ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рд╛рд░рдВрдн рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ s рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкрдХрдбрд╝реЛред рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдкрд╣рд▓рд╛ рдереНрд░реЗрдб s_constructed рдорд╛рди рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛, рд▓реЗрдХрд┐рди рдЗрд╕реЗ true рдкрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдирд╣реАрдВ рдХрд┐рдпрд╛ , рддреЛ s рдСрдмреНрдЬреЗрдХреНрдЯ рджреЛ рдмрд╛рд░ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рджреЛ рдмрд╛рд░ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛ ред (рдмрд▓реНрдХрд┐, рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ "рд▓реАрдХ", рдФрд░ рджреВрд╕рд░рд╛ рджреЛ рдмрд╛рд░ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред) рдХреЛрдИ рдЪреБрдЯрдХреБрд▓реЗ рдирд╣реАрдВ!

рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдм рдирд╣реАрдВ рд╣реИред рджреЗрдЦреЛ рдХрд┐ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдЕрдЧрд░ рджреЛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рд░ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рд╣реИрдВ:
int ComputeSomething()
{
static Something s(0);
static Something t(1);
return s.ComputeIt() + t.ComputeIt();
}

рдореЗрдореЛрд░реА рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдВрдкрд╛рдЗрд▓рд░ рджреЛрдиреЛрдВ рдЭрдВрдбреЛрдВ рдХреЛ рдПрдХ рдЪрд░ рдореЗрдВ рдмрдЪрд╛рдПрдЧрд╛ред
class Something { ... };
int ComputeSomething()
{
static char constructed = 0;
static uninitialized Something s;
if (!(constructed & 1)) {
constructed |= 1;
new(&s) Something; // s
atexit(DestructS);
}
static uninitialized Something t;
if (!(constructed & 2)) {
constructed |= 2;
new(&t) Something; // t
atexit(DestructT);
}

return s.ComputeIt() + t.ComputeIt();
}

рдЦреИрд░, рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд┐рдирд╛ рдХрд┐рд╕реА рддреБрд▓реНрдпрдХрд╛рд▓рди рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдЪрд░ рдкрд░ рддрд╛рд░реНрдХрд┐рдХ рд╕рдВрдЪрд╛рд▓рди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрдИ рд╕реВрддреНрд░ рд╣реИрдВред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдПрдХ рдзрд╛рдЧрд╛ constructed |= 1 рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИ constructed |= 1 рдЙрд╕реА рд╕рдордп рдЬрдм рджреВрд╕рд░рд╛ рдзрд╛рдЧрд╛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИ constructed |= 2 |

X86 / x64 рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рдирд┐рд░реНрджреЗрд╢ рд╣реИрдВ рдЬреЛ рд╕реАрдзреЗ рдореЗрдореЛрд░реА рдореЗрдВ рдУрдкреЗрд░рд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдХрдВрдкрд╛рдЗрд▓рд░ рдорд╢реАрди рдХреЛрдб рдЬрдирд░реЗрдЯ рдХрд░реЗрдЧрд╛
or constructed, 1
...
or constructed, 2

lock рдЙрдкрд╕рд░реНрдЧреЛрдВ рдХреЗ рдмрд┐рдирд╛, рдЗрд╕рд▓рд┐рдП рдорд▓реНрдЯреАрдкреНрд░реЛрд╕реЗрд╕рд░ рдорд╢реАрдиреЛрдВ рдкрд░ рджреЛрдиреЛрдВ рдСрдкрд░реЗрд╢рдиреЛрдВ рдореЗрдВ рд╕рдорд╛рди рдкреБрд░рд╛рдиреЗ рдореВрд▓реНрдп рдХреЛ рдкрдврд╝рдиреЗ рдХрд╛ рд╕рдордп рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╕реЗрдЯ рдмрд┐рдЯреНрд╕ рдореЗрдВ рд╕реЗ рдПрдХ "рдЦреЛ" рдЬрд╛рдПрдЧрд╛ред

Ia64 / рдЕрд▓реНрдлрд╛ рдкреНрд░реЛрд╕реЗрд╕рд░ рдореЗрдВ, рддрд╛рд░реНрдХрд┐рдХ рдирд┐рд░реНрджреЗрд╢ рдХреЗрд╡рд▓ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдПрдХрд▓-рдкреНрд░реЛрд╕реЗрд╕рд░ рдорд╢реАрди рдкрд░ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕рдВрдХрд▓рдХ рдкреНрд░рддреНрдпреЗрдХ рдСрдкрд░реЗрд╢рди рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддрд╛ рд╣реИ |= рддреАрди рдорд╢реАрди рдирд┐рд░реНрджреЗрд╢реЛрдВ рдореЗрдВ:
ldl t1,0(a0) ;
addl t1,1,t1 ;
stl t1,1,0(a0) ;

рдпрджрд┐ рдкреБрд░рд╛рдиреЗ рдореВрд▓реНрдп рдХреЛ рдкрдврд╝рдиреЗ рдФрд░ рдПрдХ рдирдпрд╛ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмреАрдЪ рдПрдХ рдереНрд░реЗрдб рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдмрд╛рдзрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдирдпрд╛ рдореВрд▓реНрдп рдЕрдиреНрдп рдереНрд░реЗрдбреНрд╕ рд╕реЗ рдХрд┐рдП рдЧрдП рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ "рдЕрдзрд┐рд▓реЗрдЦрд┐рдд" рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЦрдВрдб рджреНрд╡рд╛рд░рд╛ рд╕реНрдереИрддрд┐рдХ рдЪрд░ рдХреЗ рдЖрд░рдВрдн рдХреА рд░рдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:
int ComputeSomething()
{
EnterCriticalSection(...);
static int cachedResult = ComputeSomethingSlowly();
LeaveCriticalSection(...);
return cachedResult;
}

рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ рдЕрдм рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдзрд╛рдЧрд╛ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ ComputeSomething() рдХреЛ рдЙрд╕реА рдзрд╛рдЧреЗ рд╕реЗ рдлрд┐рд░ рд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдП? ("рд╣рдордиреЗ рдХреЙрд▓ рдХреЛ ComputeSomething() рдХрд┐рдпрд╛ рд╣реИ; рдпрд╣ рдереНрд░реЗрдб рдХреЗ рдЕрдВрджрд░ рд╕реЗ рдЖ рд░рд╣рд╛ рд╣реИ!") рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ ComputeSomethingSlowly() рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдпрд╛ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХреЙрд▓ ComputeSomething() ред (рджреВрд░ рд╕реЗ ComputeSomethingSlowly() ? рдФрд░ рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ ComputeSomethingSlowly() рдПрдХ рдбрд╛рдпрд▓реЙрдЧ рдмреЙрдХреНрд╕ рджрд┐рдЦрд╛рддрд╛ рд╣реИ, рдФрд░ DispatchMessage() рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрджреЗрд╢ рд▓реВрдк DispatchMessage() рдПрдХ рдШрдЯрдирд╛ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рд╣реИрдВрдбрд▓рд░ рдЦреБрдж ComputeSomething() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЙрд▓рд┐рдВрдЧ рд╕реНрдЯреНрд░реАрдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдиреБрднрд╛рдЧ рдХрд╛ рдорд╛рд▓рд┐рдХ рд╣реЛрдЧрд╛, рдмрд┐рдирд╛ рдХрд┐рд╕реА рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХреЗ рдЕрдВрджрд░ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдЕрд╕рдВрдЧрдард┐рдд рдореВрд▓реНрдп рдХреЛ рдкрдХрдбрд╝ рд▓реЗрдЧрд╛ред

рдЗрд╕рд▓рд┐рдП, рдЬрдм рдЖрдк рд░рдирдЯрд╛рдЗрдо рдкрд░ рдПрдХ рд╕реНрдерд┐рд░ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХрд╛ рдЖрд░рдВрдн рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рд╕рд╛рд╡рдзрд╛рди рд░рд╣реЗрдВред

рд▓реЙрдХрд▓реЗрд╕ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди


InterlockedXxx рд╕рдВрдЪрд╛рд▓рди - 32-рдмрд┐рдЯ рдореВрд▓реНрдпреЛрдВ рдФрд░ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдкрд░ рдкрд░рдорд╛рдгреБ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдХреБрд╢рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред рд▓реЗрдХрд┐рди рдкрд░рдорд╛рдгреБ рдЕрдХреЗрд▓реЗ рдзрд╛рдЧреЗ-рд╕реБрд░рдХреНрд╖рд╛ рдХреА рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред

рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЦрдВрдб рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдПрдХ рд╕рд╛рдЭрд╛ рдЪрд░ рд╣реИ, рдФрд░ рдХрд╣реАрдВ рдФрд░ рдХрд┐рд╕реА рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЖрдк рдЗрд╕ рдЪрд░ рдХреЛ рдПрдХ рд╕реЗ рдмрдврд╝рд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред "рдорд╣рд╛рди, рдореИрдВ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдиреБрднрд╛рдЧ рдХреЗ рдмрд┐рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдмрд╕ InterlockedIncrement рдХрд╣рддреЗ рд╣реИрдВред"

рд▓реЗрдХрд┐рди рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ рдХрд┐ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЦрдВрдб рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рд╣реИ рдХрд┐ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╕рдордп рдХреЛрдИ рднреА рдЪрд░ рдХрд╛ рдореВрд▓реНрдп рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ? рдЖрдкрдиреЗ рдЗрд╕реЗ рд▓рд┐рдпрд╛ рдФрд░ "рдЪреБрдкрдЪрд╛рдк" рдЗрд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ред

рдПрдХ рдФрд░ рдЧрд▓рддрдлрд╣рдореА рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЦрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬрдЯрд┐рд▓ рдкрд░рдорд╛рдгреБ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╣реИ рдХрд┐ рд╡реЗ InterlockedMultiply рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ:

// !
LONG InterlockedMultiply(volatile LONG *plMultiplicand, LONG lMultiplier)
{
EnterCriticalSection(&SomeCriticalSection);
LONG lResult = *plMultiplicand *= lMultiplier;
LeaveCriticalSection(&SomeCriticalSection);
return lResult;
}

рд╣рд╛рдВ, рдпрд╣ рдХреЛрдб рджреЛ InterlockedMultiply рдХреЙрд▓ рдХреЗ рдмреАрдЪ рд╕рдВрдШрд░реНрд╖ рдХреЛ рд░реЛрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдЪрд░ рдкрд░ рдЕрдиреНрдп рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдкрд░рдорд╛рдгреБрддрд╛ рдХреА рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓реЗрдВ:

int x = 2;
Thread1()
{
InterlockedIncrement(&x);
}

Thread2()
{
InterlockedMultiply(&x, 5);
}

рдпрджрд┐ рдЧреБрдгрд╛ рдкрд░рдорд╛рдгреБ рд╣реИ, рддреЛ рджреЛ рдСрдкрд░реЗрд╢рдиреЛрдВ рдХрд╛ рдкрд░рд┐рдгрд╛рдо x = 15 рдпрд╛ x = 11 рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдСрдкрд░реЗрд╢рди рдкрд╣рд▓реЗ рдкреВрд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ "рдкрд░рдорд╛рдгреБ" рдЧреБрдгрди рд╣рдореЗрдВ рдЕрдиреНрдп рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдХрд╛рдлреА рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд:

рд╕реНрдЯреНрд░реАрдо 1рд╕реНрдЯреНрд░реАрдо 2
рд╕реНрд░реЛрдд: x = реи
InterlockedMultiply(&x, 5)
EnterCriticalSection
x рдкрдврд╝реЗрдВ (рдкрдврд╝реЗрдВ: 2)
InterlockedIncrement(&x);
рдЕрдм x = 3
5 рд╕реЗ рдЧреБрдгрд╛ рдХрд░реЗрдВ (рдкрд░рд┐рдгрд╛рдо: 10)
рд▓рд┐рдЦрдирд╛ x (рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдпрд╛ рдЧрдпрд╛: 10)
LeaveCriticalSection
рдкрд░рд┐рдгрд╛рдо: x = 10
рдЗрддрдирд╛ рдкрд░рдорд╛рдгреБ рдирд╣реАрдВ! рдЗрд╕реЗ рдХреИрд╕реЗ рдареАрдХ рдХрд░реЗрдВ?

рдпрджрд┐ рдСрдкрд░реЗрд╢рди рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рд╡реИрд╢реНрд╡рд┐рдХ рдбреЗрдЯрд╛ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рдПрдХ "рд╢реБрджреНрдз рдХрд╛рд░реНрдп" рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рдкрд░рдорд╛рдгреБ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП InterlockedCompareExchange рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

LONG InterlockedMultiply(volatile LONG *plMultiplicand, LONG lMultiplier)
{
LONG lOriginal, lResult;
do {
lOriginal = *plMultiplicand;
lResult = lOriginal * lMultiplier;
} while (InterlockedCompareExchange(plMultiplicand,
lResult, lOriginal) != lOriginal);
return lResult;
}

рдСрдкрд░реЗрд╢рди рдореЗрдВ рддреАрди рдЪрд░рдг рд╣реЛрддреЗ рд╣реИрдВред

рдкрд╣рд▓рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рдиреЛрдВ рдХрд╛ "рдХреИрдкреНрдЪрд░" рд╣реИ: lOriginal = *plMultiplicand;

рджреВрд╕рд░рд╛ рдкрдХрдбрд╝реЗ рдЧрдП рдореВрд▓реНрдпреЛрдВ рдкрд░ рдХрд╛рд░реНрд░рд╡рд╛рдИ рд╣реИ: lResult = lOriginal * lMultiplier;

рддреАрд╕рд░рд╛ рдХреЗрд╡рд▓ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдпрджрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рди рдирд╣реАрдВ рдмрджрд▓реЗ рд╣реИрдВ: InterlockedCompareExchange(plMultiplicand, lResult, lOriginal)

рдпрджрд┐ рд╡реЗ рдмрджрд▓ рдЧрдП рд╣реИрдВ, рддреЛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рдСрдкрд░реЗрд╢рди рдХрд┐рд╕реА рдЕрдиреНрдп рд╕реЗ рдЖрдЧреЗ рдирд┐рдХрд▓ рдЧрдпрд╛ рдерд╛; рдФрд░ рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдСрдкрд░реЗрд╢рди рдХреЛ рджреЛрд╣рд░рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдкрд░ рд▓реМрдЯрддреЗ рд╣реБрдП: InterlockedIncrement рдкрд░ рдПрдХ рдЖрдХреНрд░рдордг рдХреЙрд▓ рдХреЗ рдмрд╛рдж InterlockedIncrement рдСрдкрд░реЗрд╢рди рдзреНрдпрд╛рди рджреЗрдЧрд╛ рдХрд┐ x рдХрд╛ рдорд╛рди рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд╕реЗ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдЧрд╛ред InterlockedCompareExchange рдореЗрдВ рддреБрд▓рдирд╛ рдХреА рдкрд░рдорд╛рдгреБрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдо рдХреЗрд╡рд▓ рддрднреА рджрд░реНрдЬ рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗ рдЬрдм рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рдмрджрд▓реЗ рдЧрдП рд╣реЛрдВред

рдЗрд╕ рддрдереНрдп рдкрд░ рдзреНрдпрд╛рди рди рджреЗрдВ рдХрд┐ рдСрдкрд░реЗрд╢рди рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП! InterlockedCompareExchange рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ InterlockedCompareExchange рдЕрд╕рдорд░реНрде рд╣реИ рдХрд┐ рдСрдкрд░реЗрд╢рди рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВред рдЕрдиреНрдпрдерд╛, "рдПрдмреАрдП рд╕рдорд╕реНрдпрд╛" рдирд╛рдордХ рдПрдХ рд╕реНрдерд┐рддрд┐ рд╕рдВрднрд╡ рд╣реИ: рдСрдкрд░реЗрд╢рди рдХреЗ рдкрд╣рд▓реЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди, рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рди рдП рдерд╛; рдлрд┐рд░, рдмрд╣рддреЗ рдзрд╛рдЧреЗ рд╕реЗ рдХрд┐рд╕реА рдХрд╛ рдзреНрдпрд╛рди рдирд╣реАрдВ рдЧрдпрд╛, рддреЛ рдЙрд╕рдХрд╛ рдорд╛рди B рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛, рдФрд░ рдлрд┐рд░ A. InterlockedCompareExchange рдзреНрдпрд╛рди рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдХреБрдЫ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдкрд╣рд▓реА рдмрд╛рд░ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдорд╛рди рдХреЛ рдмрдЪрд╛рдПрдЧрд╛ред рдпрджрд┐ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЕрдиреНрдп рдбреЗрдЯрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдмрджрд▓ рдЧрдП рд╣реИрдВ, рддреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкрд░рд┐рдгрд╛рдо рдЧрд▓рдд рд╣реЛрдЧрд╛ред



рдпрджрд┐ рдкрд░рдорд╛рдгреБ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЪрд░ рдкрд░ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рддреЛ рдЗрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдиреБрднрд╛рдЧ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА; рдкреНрд░рджрд░реНрд╢рди, рдФрд░ рдорд╛рдкрдиреАрдпрддрд╛, рдФрд░ рд╕рд┐рд╕реНрдЯрдо рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЦрдкрдд рдореЗрдВ рджреЛрдиреЛрдВ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд░рдиреЗ рдХреЗ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ "рд▓реЙрдХрд▓реЗрд╕ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди" рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рд▓рд╛рдн рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдЗрд╕ рддрдереНрдп рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ рдХрд┐ рдпрджрд┐ рдХреЛрдИ рдереНрд░реЗрдб рд▓реЙрдХ (рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЦрдВрдб, рдореНрдпреВрдЯреЗрдХреНрд╕, рд╕реЗрдорд╛рдлреЛрд░, рдЖрджрд┐) рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░, рдПрдХ рдХрд╛рд░рдг рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЗ рд▓рд┐рдП, "рдЕрдЯрдХ рдЬрд╛рддрд╛ рд╣реИ", рддреЛ рд╕рднреА рдПрдХ рд╣реА рд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрд╣рддреЗ рд╣реИрдВ, " рдлрдВрд╕ рдЬрд╛рдУ тАЭрдЙрд╕рдХреЗ рдмрд╛рджред рд▓реЙрдХрд▓реЗрд╕ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд╕рд╛рде, рдПрдХ рднреА "рдЕрдЯрдХрд╛ рд╣реБрдЖ" рдзрд╛рдЧрд╛ рдкреВрд░реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рд╕реНрдЯрд╛рд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ: рдЪрд╛рд╣реЗ рдХрд┐рддрдиреЗ рднреА рдереНрд░реЗрдбреНрд╕ "рдЕрдЯрдХреЗ" рд╣реЛрдВ, рдХрдо рд╕реЗ рдХрдо рдПрдХ рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рд╣реЗрдЧрд╛ред рд▓реЙрдХрд▓реЗрд╕ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рд░рд┐рдпрд▓-рдЯрд╛рдЗрдо рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдорд╛рдВрдЧ рдореЗрдВ рд╣реИ, рдЬрд╣рд╛рдВ рдХрд╛рд░реНрдп рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрд╕реЗрд╕рд░ рд╕рдордп рдХреЗ рдЖрд╡рдВрдЯрди рдХреЗ vicissitudes рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд▓реЙрдХрд▓реЗрд╕ рдереНрд░реЗрдб-рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд▓рд╕реА рдЖрд░рдВрднреАрдХрд░рдг


рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдо рдПрдХ-рджреВрд╕рд░реЗ рдХреЛ рдЪрдВрдЪрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд▓рд╕реА рд╣реЛрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд░рддреЗ рд╣реИрдВред рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ, рдпрд╣ рд╕реАрдзрд╛ рд╣реИ:

// a b : a тЙе 0 b тЙе a.
// -1 ,
// " "
int a = -1, b = -1;

void LazyInitialize()
{
if (a != -1) return; //

a = calculate_nominal_a();
b = calculate_nominal_b();

//
a = max(0, a);
b = max(a, b);
}

рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдПрдХ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ, рдЗрд╕ рддрд░рд╣ рдХреЗ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рд╕реЗ рдЙрдбрд╝рд╛рди рдХреА рд╕реНрдерд┐рддрд┐ рдмрди рд╕рдХрддреА рд╣реИ:
рд╕реНрдЯреНрд░реАрдо 1рд╕реНрдЯреНрд░реАрдо 2
if (a != -1) [рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ]
a = calculate_nominal_a(); // рд░рд┐рдЯрд░реНрди 2
if (a != -1) return; // рдмрд╣реБрдд рдЬрд▓реНрджреА!
рдкрд╣рд▓реЗ рдзрд╛рдЧреЗ рдиреЗ b рдЧрдгрдирд╛ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдмрд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рджреВрд╕рд░рд╛ рдзрд╛рдЧрд╛ рдЗрд╕рдХреЗ рдЕрд╕рдорд╛рди рдореВрд▓реНрдп рдХреЛ рд▓реЗ рдЬрд╛рдПрдЧрд╛ред

тАЬрдЖрд╣, рдпрд╣ рдареАрдХ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ! рдпрд╣ рдЬрд╛рдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдЖрд░рдВрднреАрдХрд░рдг рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд╣рдо рдЬрд╛рдБрдЪреЗрдВрдЧреЗ рдХрд┐ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди b ред "

void LazyInitialize()
{
if ( b != -1) return; //

a = calculate_nominal_a();
b = calculate_nominal_b();

//
a = max(0, a);
b = max(a, b);
}

рдПрдпрд░ рдХрдВрдбреАрд╢рдирд┐рдВрдЧ рдЕрднреА рднреА рд╕рдВрднрд╡ рд╣реИ:
рд╕реНрдЯреНрд░реАрдо 1рд╕реНрдЯреНрд░реАрдо 2
if (b != -1) [рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рд╣реБрдЖ]
a = calculate_nominal_a(); // рд░рд┐рдЯрд░реНрди 2
b = calculate_nominal_b(); // 1 рд░рд┐рдЯрд░реНрди
if (b != -1) return; // рдмрд╣реБрдд рдЬрд▓реНрджреА!
рджреВрд╕рд░рд╛ рдзрд╛рдЧрд╛ рдорд╛рдиреЛрдВ рдХреЛ a рдФрд░ b рд▓реЗрдЧрд╛ рдЬреЛ рд▓рдЧрд╛рдП рдЧрдП рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред

тАЬрдЖрдк рдЦреБрдж рдХреЛ рдЗрд╕рд╕реЗ рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ! рдореИрдВ рд╕реНрдерд╛рдиреАрдп рдЪрд░реЛрдВ рдореЗрдВ a рдФрд░ b рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░реВрдВрдЧрд╛, рдФрд░ рдЧрдгрдирд╛ рдкреВрд░реНрдг рд╣реЛрдиреЗ рдкрд░ рд╣реА рдЙрдиреНрд╣реЗрдВ рд╡реИрд╢реНрд╡рд┐рдХ рд░реВрдк рд╕реЗ рд▓рд┐рдЦреВрдВрдЧрд╛, рддрд╛рдХрд┐ рджреВрд╕рд░рд╛ рдзрд╛рдЧрд╛ "рдЕрд░реНрдз-рд╕рдорд╛рдкреНрдд" рдорд╛рдиреЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рди рд╣реЛред

void LazyInitialize()
{
if (b != -1) return; //

//
int temp_a
= calculate_nominal_a();
int temp_b = calculate_nominal_b();

//
temp_a = max(0, temp_a );
temp_b = max( temp_a, temp_b );

//
a = temp_a;
b = temp_b;

}

рд▓рдЧрднрдЧ рд╕рд╣реА; рд▓реЗрдХрд┐рди рдЙрдбрд╝рд╛рди рдХрдВрдбреАрд╢рдирд┐рдВрдЧ рдЕрднреА рднреА рд╕рдВрднрд╡ рд╣реИ:
рд╕реНрдЯреНрд░реАрдо 1рд╕реНрдЯреНрд░реАрдо 2
if (b != -1) [рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рд╣реБрдЖ]
temp_a = calculate_nominal_a(); // рд░рд┐рдЯрд░реНрди 2
temp_b = calculate_nominal_b(); // 1 рд░рд┐рдЯрд░реНрди
temp_a = max(0, temp_a); // temp_a = 2
temp_b = max(temp_a, temp_b); // temp_b = 2
a = temp_a; // рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреИрд╢ рдХреЛ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ
b = temp_b; // рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреИрд╢ рдХреЛ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ
b рдорд╛рди рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
if (b != -1) return; // рдмрд╣реБрдд рдЬрд▓реНрджреА!
рдХрд╛ рдорд╛рди рд╕реНрдореГрддрд┐ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
рдХрдВрдкрд╛рдЗрд▓рд░ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ рдХрд┐ b рдХрд╛ рдирдпрд╛ рдореВрд▓реНрдп рдЕрдиреНрдп рдкреНрд░реЛрд╕реЗрд╕рд░ рд╕реЗ рдкрд╣рд▓реЗ рдХреЗ рдирдП рдореВрд▓реНрдп рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧрд╛ред рдпрджреНрдпрдкрд┐ рдкреНрд░реЛрд╕реЗрд╕рд░ рдЗрд╕ рдХреНрд░рдо рдореЗрдВ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХрд░рддрд╛ рд╣реИ, рдПрдХ рдорд▓реНрдЯреАрдкреНрд░реЛрд╕реЗрд╕рд░ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реА рдХрдВрдЯреНрд░реЛрд▓ рд╕рд░реНрдХрд┐рдЯ рдХреЛ рдЙрдиреНрд╣реЗрдВ рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдЕрдзрд┐рдХрд╛рд░ рд╣реИ, рддрд╛рдХрд┐ рдЕрдиреНрдп рдкреНрд░реЛрд╕реЗрд╕рд░ a = -1 рдФрд░ b = 2 рджреЗрдЦреЗрдВред

рдореЗрдореЛрд░реА рдХреЗ рд▓рд┐рдП b рд▓рд┐рдЦрдирд╛ рдПрдХ рд░рд┐рд▓реАрдЬ рдСрдкрд░реЗрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП; рдЗрд╕рдХреЗ рдмрд╛рдж рдкрд┐рдЫрд▓реЗ рд╕рднреА рдСрдкрд░реЗрд╢рдиреЛрдВ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рдкрд░рд┐рд▓рдХреНрд╖рд┐рдд рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЕрдиреНрдп рдкреНрд░реЛрд╕реЗрд╕рд░ рдирдпрд╛ рдореВрд▓реНрдп рджреЗрдЦреЗрдВред

void LazyInitialize()
{
if (b != -1) return; //

//
int temp_a = calculate_nominal_a();
int temp_b = calculate_nominal_b();

//
temp_a = max(0, temp_a);
temp_b = max(temp_a, temp_b);

//
a = temp_a;
// b
// , ,
// Release
InterlockedCompareExchangeRelease(
reinterpret_cast<LONG*>&b, temp_b, -1);

}

рдкрд░рд┐рдгрд╛рдореА рдХреЛрдб рдПрдХ рдмрд┐рдирд╛ рдЪрд╛рдмреА рд╡рд╛рд▓реЗ рдкрд░рдорд╛рдгреБ рдСрдкрд░реЗрд╢рди рдХреЗ рд╕рдорд╛рди рд╣реИ, рдХреЗрд╡рд▓ рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд┐рдирд╛: рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рднреА рдЧрдгрдирд╛ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдПрдХрд▓ InterlockedCompareExchangeRelease рдХрд┐рдП рдЧрдП InterlockedCompareExchangeRelease рдСрдкрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рдореЗрдореЛрд░реА рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдорд╛рдирдХрд░ рдХрд┐ calculate_nominal_a() рдФрд░ calculate_nominal_b() рд╣рдореЗрд╢рд╛ рд╕рдорд╛рди рдорд╛рди рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдСрдкрд░реЗрд╢рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдпрджрд┐ рдпрд╣ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ: рдпрджрд┐ рдЪрд░ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЖрд░рдВрднреАрдХреГрдд рдирд╣реАрдВ рдХрд┐рдП рдЧрдП рдереЗ, рддреЛ рдПрдХ рдФрд░ рдзрд╛рдЧрд╛ рдиреЗ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдХрд╛рдо рдХрд┐рдпрд╛ред (рдзреНрдпрд╛рди рджреЗрдВ: рдпрджрд┐ InterlockedCompareExchangeRelease рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИ, рддреЛ рдЪрд░ рдЕрднреА рднреА рд╣рдорд╛рд░реА рд╕реНрдЯреНрд░реАрдо рджреНрд╡рд╛рд░рд╛ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛!)

рдЕрдВрдд рдореЗрдВ, рд░реЗрдордВрдб рдиреЗ рдПрдХ рдкрд╣реЗрд▓реА рдХрд╛ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛: рдХреНрдпрд╛ рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ temp_a рдмрд┐рдирд╛ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ? рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдереНрд░реЗрдб рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд╛рдж рд╣реА рдореВрд▓реНрдп рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЖрд░рдВрднреАрдХрд░рдг рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред

Source: https://habr.com/ru/post/In118390/


All Articles