demolg.pp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. program testlg;
  2. {$mode objFPC}
  3. {$modeswitch advancedrecords}
  4. Uses
  5. {$ifdef unix}
  6. cthreads,
  7. {$endif}
  8. sysutils,
  9. classes,
  10. syncobjs;
  11. type
  12. { TLockGuard }
  13. generic TLockGuard<T:TSynchroObject> = record
  14. obj: T;
  15. class operator Initialize(var hdl: TLockGuard);
  16. class operator Finalize(var hdl: TLockGuard);
  17. procedure Init(AObj: T);
  18. end;
  19. class operator TLockGuard.Initialize(var hdl: TLockGuard);
  20. begin
  21. hdl.obj := nil;
  22. end;
  23. class operator TLockGuard.Finalize(var hdl: TLockGuard);
  24. begin
  25. if (hdl.obj=nil) then
  26. exit;
  27. hdl.obj.Release();
  28. end;
  29. procedure TLockGuard.Init(AObj:T);
  30. begin
  31. self.obj := AObj;
  32. self.obj.Acquire();
  33. end;
  34. Function Fibonacci(TN,N : Integer) : Int64;
  35. Var
  36. Next,Last : Int64;
  37. I : Integer;
  38. begin
  39. if N=0 then
  40. exit(0);
  41. Result:=1;
  42. Last:=0;
  43. for I:=1 to N-1 do
  44. begin
  45. Next:=Result+last;
  46. Last:=Result;
  47. Result:=Next;
  48. Writeln('Thread['+IntToStr(TN)+'] '+IntToStr(Result));
  49. end;
  50. end;
  51. var
  52. ThreadCount : Integer;
  53. ExecuteCount : Integer;
  54. Type
  55. { TCalcThread }
  56. TCalcThread = Class(TThread)
  57. Public
  58. class var ExecuteLock : TCriticalSection;
  59. Private
  60. FNo : Integer;
  61. Public
  62. constructor create(aNo : Integer);
  63. destructor destroy; override;
  64. Procedure Execute; override;
  65. end;
  66. { TCalcThread }
  67. constructor TCalcThread.create(aNo : Integer);
  68. begin
  69. Inherited Create(False);
  70. InterlockedIncrement(ThreadCount);
  71. FNo:=aNo;
  72. Writeln('Creating thread ',FNo);
  73. FreeOnTerminate:=True;
  74. end;
  75. destructor TCalcThread.destroy;
  76. begin
  77. InterlockedDecrement(ThreadCount);
  78. Inherited;
  79. end;
  80. procedure TCalcThread.Execute;
  81. var
  82. lock : specialize TLockGuard<TCriticalSection>;
  83. Res : Integer;
  84. begin
  85. lock.Init(ExecuteLock);
  86. InterlockedIncrement(ExecuteCount);
  87. if ExecuteCount<>1 then
  88. Writeln('Error : multiple threads are executing (start)');
  89. Res:=Fibonacci(FNo,10);
  90. writeln('Thread['+IntTostr(FNo),'] Fibonacci(10) = '+IntToStr(Res));
  91. InterlockedDecrement(ExecuteCount);
  92. if ExecuteCount<>0 then
  93. Writeln('Error : multiple threads are executing (stop)');
  94. end;
  95. var
  96. I : integer;
  97. begin
  98. TCalcThread.ExecuteLock:=TCriticalSection.Create;
  99. for I:=1 to 10 do
  100. TCalcThread.Create(i);
  101. repeat
  102. sleep(10);
  103. CheckSynchronize;
  104. until (ThreadCount=0);
  105. end.