рдкрд░рдорд╛рдгреБ рд╕рдВрдЪрд╛рд▓рди

рдмрд╕ рджреВрд╕рд░реЗ рджрд┐рди рдЙрдиреНрд╣реЛрдВрдиреЗ рдореБрдЭрд╕реЗ рдПрдХ рд╕рд╡рд╛рд▓ рдХрд┐рдпрд╛ред

рдФрд░ рдЖрдкрдХреЛ рд╕рд┐рд╕реНрдЯрдо рдореЙрдбреНрдпреВрд▓ рд╕реЗ _LStrClr рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ LOCK рдЙрдкрд╕рд░реНрдЧ, рдпрд╛ рдЗрд╕рдХреЗ рдПрдирд╛рд▓реЙрдЧ рдЗрдВрдЯрд░рд▓реЙрдХрдбecrement рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИред рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд▓рд╛рдЗрди рдХреЗ рд▓рд┐рдВрдХ рд╕рдВрджрд░реНрдн рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рдШрдЯрд╛рддреА рд╣реИ рдФрд░ рдЬрдм рдпрд╣ рд░реАрд╕реЗрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд▓рд╛рдЗрди рджреНрд╡рд╛рд░рд╛ рдкрд╣рд▓реЗ рд╕реЗ рдХрдмреНрдЬрд╛ рдХреА рдЧрдИ рдореЗрдореЛрд░реА рдХреЛ рдореБрдХреНрдд рдХрд░ рджреЗрддрд╛ рд╣реИред

рдкреНрд░рд╢реНрди рдХрд╛ рд╕рд╛рд░ рдпрд╣ рдерд╛: рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рдирд╛ рд▓рдЧрднрдЧ рдЕрд╕рдВрднрд╡ рд╣реИ рдЬрд╣рд╛рдВ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рджреЛ рдереНрд░реЗрдбреНрд╕ рд╕реЗ рдПрдХ рд╕рд╛рде refs рдЦреЛ рджреЗрдЧреА, рдФрд░ рдЗрд╕рд▓рд┐рдП рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдкрд░рдорд╛рдгреБ рдСрдкрд░реЗрд╢рди рдмреЗрдорд╛рдиреА рд╣реИред

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдЖрдзрд╛рд░ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рд▓реЗрдХрд┐рди ...

рд▓реЗрдХрд┐рди рд╣рдо рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдереНрд░реЗрдб рдХреНрд▓рд╛рд╕ рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
рдпрд╣ рдХрдо рд╕реЗ рдХрдо refCnt рдореЗрдВ рд╡реГрджреНрдзрд┐ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕рдВрджрд░реНрдн рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рдЕрдкрдШрдЯрд┐рдд рдХрд░рддреЗ рд╕рдордп рдкрд░рдорд╛рдгреБ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдореЗрдореЗрд▓рдХ рдХреЛ "рдкреНрд░рд╛рдкреНрдд" рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ _LStrClr рдХреЛрдб рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:

procedure _LStrClr(var S); {$IFDEF PUREPASCAL} var P: PStrRec; begin if Pointer(S) <> nil then begin P := Pointer(Integer(S) - Sizeof(StrRec)); Pointer(S) := nil; if P.refCnt > 0 then if InterlockedDecrement(P.refCnt) = 0 then FreeMem(P); end; end; {$ELSE} asm { -> EAX pointer to str } MOV EDX,[EAX] { fetch str } TEST EDX,EDX { if nil, nothing to do } JE @@done MOV dword ptr [EAX],0 { clear str } MOV ECX,[EDX-skew].StrRec.refCnt { fetch refCnt } DEC ECX { if < 0: literal str } JL @@done LOCK DEC [EDX-skew].StrRec.refCnt { threadsafe dec refCount } JNE @@done PUSH EAX LEA EAX,[EDX-skew].StrRec.refCnt { if refCnt now zero, deallocate} CALL _FreeMem POP EAX @@done: end; {$ENDIF} 


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

рдмреЗрд╢рдХ, рдореИрдВрдиреЗ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рдЗрдВрдЯреЗрд▓ рдореИрдиреБрдЕрд▓ рд╕реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдЬрд╣рд╛рдВ рдХрд╛рдо рд╕рдордЭрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрдд рдореЗрдВ рдореИрдВрдиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ (рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдореИрдВ рдкреНрд░рд╢реНрди рдХреЗ рд▓реЗрдЦрдХ рдХреЛ рд╕рдордЭрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛):

 program interlocked; {$APPTYPE CONSOLE} uses Windows; const Limit = 1000000; DoubleLimit = Limit shl 1; var SameGlobalVariable: Integer; function Test1(lpParam: Pointer): DWORD; stdcall; var I: Integer; begin for I := 0 to Limit - 1 do asm lea eax, SameGlobalVariable inc [eax] //   end; end; function Test2(lpParam: Pointer): DWORD; stdcall; var I: Integer; begin for I := 0 to Limit - 1 do asm lea eax, SameGlobalVariable lock inc [eax] //   end; end; var I: Integer; hThread: THandle; ThreadID: DWORD; begin //     SameGlobalVariable SameGlobalVariable := 0; hThread := CreateThread(nil, 0, @Test1, nil, 0, ThreadID); for I := 0 to Limit - 1 do asm lea eax, SameGlobalVariable inc [eax] //   end; WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); if SameGlobalVariable <> DoubleLimit then Writeln('Step one failed. Expected: ', DoubleLimit, ' but current: ', SameGlobalVariable); //     SameGlobalVariable SameGlobalVariable := 0; hThread := CreateThread(nil, 0, @Test2, nil, 0, ThreadID); for I := 0 to Limit - 1 do asm lea eax, SameGlobalVariable lock inc [eax] //   end; WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); if SameGlobalVariable <> DoubleLimit then Writeln('Step two failed. Expected: ', DoubleLimit, ' but current: ', SameGlobalVariable); Readln; end. 


рдЙрджрд╛рд╣рд░рдг рдХрд╛ рд╕рд╛рд░ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рд╣реИ SameGlobalVariable (рдпрд╣ рдХрд╛рд░реНрдп рдХреЗ рдореВрд▓ рдХрдерди рд╕реЗ рд▓рд╛рдЗрди рд▓рд┐рдВрдХ рдХреЗ рдХрд╛рдЙрдВрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ) рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдФрд░ рдкрд░рдорд╛рдгреБ рдореЛрдб рдореЗрдВ рдПрдХ рдереНрд░реЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдпрд╣рд╛рдВ рдЖрдк рдСрдкрд░реЗрд╢рди рдХреЗ рджреЛ рддрд░реАрдХреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред
рдХрдВрд╕реЛрд▓ рдореЗрдВ, рдЖрдкрдХреЛ рдирд┐рдореНрди рдЬреИрд╕рд╛ рдХреБрдЫ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

 Step one failed. Expected: 2000000 but current: 1018924 

рджреВрд╕рд░реА рдЕрд╡рддрд╛рд░ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпрд╛рдБ рдЬреЛ рдЖрдкрдиреЗ рдХрднреА рдирд╣реАрдВ рджреЗрдЦреА рд╣реЛрдВрдЧреАред

рд╡реИрд╕реЗ, рдкрд╣рд▓реЗ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд╛рдлреА рдЕрдЪреНрдЫреЗ рд░реИрдВрдбрдорд╛рдЗрдЬрд╝рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЬреЛ рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ рдмрд╛рдд рдХреА рдереА)ред

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ:

рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдбреЗрд▓реНрдлреА рдФрд░ рд╡реАрд╕реАрдПрд▓ рд╕рд┐рд╕реНрдЯрдо рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрднреА-рдХрднреА рдЖрдкрдХреЛ рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рджреЗ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдПрдХ рддрдереНрдп рд╣реИ, рд▓реЗрдХрд┐рди ...



рдирд╣реАрдВ, рдпрд╣ рдПрдХ рддрдереНрдп рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдПрдХ рддрдереНрдп рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ - рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдерд╛

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


All Articles