简略单纯高效的Delphi原子队列

本文供给Delphi一个基于原子操纵的无锁队列,简略单纯高效。实用于多线程大吞吐量操纵的队列。

科学是使人精力变得大胆的最好路子。可用于Android体系和32,64位Windows体系。

 

感激歼10和qsl供给了批改建议!

有如下题目:

1.必须实现开辟内存

2.队列大小必须是2的幂

3.不克不及压入空指针

 

  1. unit utAtomFIFO;  
  2.   
  3. interface  
  4.   
  5. Uses  
  6.   SysUtils,  
  7.   SyncObjs;  
  8.   
  9. Type  
  10.   TAtomFIFO = Class  
  11.   Protected  
  12.     FWritePtr: Integer;  
  13.     FReadPtr: Integer;  
  14.     FCount:Integer;  
  15.     FHighBound:Integer;  
  16.     FisEmpty:Integer;  
  17.     FData: array of Pointer;  
  18.     function GetSize:Integer;  
  19.   Public  
  20.     procedure Push(Item: Pointer);  
  21.     function Pop: Pointer;  
  22.     Constructor Create(Size: Integer); Virtual;  
  23.     Destructor Destroy; Override;  
  24.     Procedure Empty;  
  25.     property Size: Integer read GetSize;  
  26.     property UsedCount:Integer read FCount;  
  27.   End;  
  28.   
  29. Implementation  
  30.   
  31. {¥I InterlockedAPIs.inc}  
  32. //创建队列,大小必须是2的幂,须要开辟足够大的队列,防止队列溢出  
  33.   
  34. Constructor TAtomFIFO.Create(Size: Integer);  
  35. var  
  36.   i:NativeInt;  
  37.   OK:Boolean;  
  38. Begin  
  39.   Inherited Create;  
  40.   OK:=(Size and (Size-1)=0);  
  41.   
  42.   if not OK then raise Exception.Create(""FIFO长度必须大于便是256并为2的幂"");  
  43.   
  44.   try  
  45.     SetLength(FData, Size);  
  46.     FHighBound:=Size-1;  
  47.   except  
  48.     Raise Exception.Create(""FIFO申请内存失败"");  
  49.   end;  
  50. End;  
  51.   
  52. Destructor TAtomFIFO.Destroy;  
  53. Begin  
  54.   SetLength(FData, 0);  
  55.   Inherited;  
  56. End;  
  57.   
  58. procedure TAtomFIFO.Empty;  
  59. begin  
  60.   while (InterlockedExchange(FReadPtr, 0)<>0) and (InterlockedExchange(FWritePtr, 0)<>0) and (InterlockedExchange(FCount, 0)<>0) do;  
  61. end;  
  62.   
  63. function TAtomFIFO.GetSize: Integer;  
  64. begin  
  65.   Result:=FHighBound+1;  
  66. end;  
  67.   
  68. procedure TAtomFIFO.Push(Item:Pointer);  
  69. var  
  70.   N:Integer;  
  71. begin  
  72.   if Item=nil then Exit;  
  73.   
  74.   N:=InterlockedIncrement(FWritePtr) and FHighBound;  
  75.   FData[N]:=Item;  
  76.   InterlockedIncrement(FCount);  
  77. end;  
  78.   
  79. Function TAtomFIFO.Pop:Pointer;  
  80. var  
  81.   N:Integer;  
  82. begin  
  83.   if InterlockedDecrement(FCount)<0 then  
  84.   begin  
  85.     InterlockedIncrement(FCount);  
  86.     Result:=nil;  
  87.   end  
  88.   else  
  89.   begin  
  90.     N:=InterlockedIncrement(FReadPtr) and FHighBound;  
  91.     while FData[N]=nil do Sleep(1);  
  92.     Result:=FData[N];  
  93.   
  94.     FData[N]:=nil;  
  95.   end;  
  96. end;  
  97.   
  98. End.  

  

 InterlockedAPIs.inc

  1. {*******************************************************}  
  2. {                                                       }  
  3. {           CodeGear Delphi Runtime Library             }  
  4. {                                                       }  
  5. { Copyright(c) 1995-2014 Embarcadero Technologies, Inc. }  
  6. {                                                       }  
  7. {*******************************************************}  
  8.   
  9. {¥IFDEF CPUX86}  
  10.   
  11. function InterlockedAdd(var Addend: Integer; Increment: Integer): Integer;  
  12. asm  
  13.       MOV   ECX,EAX  
  14.       MOV   EAX,EDX  
  15.  LOCK XADD  [ECX],EAX  
  16.       ADD   EAX,EDX  
  17. end;  
  18.   
  19. function InterlockedCompareExchange(var Target: Integer; Exchange: Integer; Comparand: Integer): Integer;  
  20. asm  
  21.       XCHG    EAX,ECX  
  22.  LOCK CMPXCHG [ECX],EDX  
  23. end;  
  24.   
  25. function InterlockedCompareExchangePointer(var Target: Pointer; Exchange: Pointer; Comparand: Pointer): Pointer;  
  26. asm  
  27.       JMP InterlockedCompareExchange  
  28. end;  
  29.   
  30. function InterlockedDecrement(var Addend: Integer): Integer;  
  31. asm  
  32.       MOV   EDX,-1  
  33.       JMP   InterlockedAdd  
  34. end;  
  35.   
  36. function InterlockedExchange(var Target: Integer; Value: Integer): Integer;  
  37. asm  
  38.       MOV     ECX,EAX  
  39.       MOV     EAX,[ECX]  
  40. @@loop:  
  41.  LOCK CMPXCHG [ECX],EDX  
  42.       JNZ     @@loop  
  43. end;  
  44.   
  45. function InterlockedExchangePointer(var Target: Pointer; Value: Pointer): Pointer;  
  46. asm  
  47.       JMP InterlockedExchange  
  48. end;  
  49.   
  50. function InterlockedIncrement(var Addend: Integer): Integer;  
  51. asm  
  52.       MOV   EDX,1  
  53.       JMP   InterlockedAdd  
  54. end;  
  55.   
  56. {¥ENDIF CPUX86}  
  57.   
  58. {¥IFDEF CPUX64}  
  59.   
  60. function InterlockedExchangeAdd(var Addend: Integer; Value: Integer): Integer;  
  61. asm  
  62.       .NOFRAME  
  63.       MOV   EAX,EDX  
  64.  LOCK XADD  [RCX].Integer,EAX  
  65. end;  
  66.   
  67. function InterlockedDecrement(var Addend: LongInt): LongInt;  
  68. asm  
  69.       .NOFRAME  
  70.       MOV   EAX,-1  
  71.  LOCK XADD  [RCX].Integer,EAX  
  72.       DEC   EAX  
  73. end;  
  74.   
  75. function InterlockedIncrement(var Addend: LongInt): LongInt;  
  76. asm  
  77.       MOV   EAX,1  
  78.  LOCK XADD  [RCX].Integer,EAX  
  79.       INC   EAX  
  80. end;  
  81.   
  82. function InterlockedCompareExchange(var Destination: Integer; Exchange: Integer; Comparand: Integer): Integer;  
  83. asm  
  84.       .NOFRAME  
  85.       MOV     EAX,R8d  
  86.  LOCK CMPXCHG [RCX].Integer,EDX  
  87. end;  
  88.   
  89. function InterlockedCompareExchange64(var Destination: Int64; Exchange: Int64; Comparand: Int64): Int64; overload;  
  90. asm  
  91.       .NOFRAME  
  92.       MOV     RAX,R8  
  93.  LOCK CMPXCHG [RCX],RDX  
  94. end;  
  95.   
  96. function InterlockedCompareExchangePointer(var Destination: Pointer; Exchange: Pointer; Comparand: Pointer): Pointer;  
  97. asm  
  98.       .NOFRAME  
  99.       MOV     RAX,R8  
  100.  LOCK CMPXCHG [RCX],RDX  
  101. end;  
  102.   
  103. function InterlockedExchangePointer(var Target: Pointer; Value: Pointer): Pointer;  
  104. asm  
  105.        .NOFRAME  
  106.   LOCK XCHG [RCX],RDX  
  107.        MOV RAX,RDX  
  108. end;  
  109.   
  110. function InterlockedExchange(var Target: Integer; Value: Integer): Integer;// inline;  
  111. asm  
  112.        .NOFRAME  
  113.   LOCK XCHG [RCX],EDX  
  114.        MOV EAX,EDX  
  115. end;  
  116.   
  117. {¥ENDIF CPUX64}  
  118.   
  119. {¥IFDEF CPUARM}  
  120.   
  121. function InterlockedAdd(var Addend: Integer; Increment: Integer): Integer;  
  122. begin  
  123.   Result := AtomicIncrement(Addend, Increment);  
  124. end;  
  125.   
  126. function InterlockedCompareExchange(var Target: Integer; Exchange: Integer; Comparand: Integer): Integer;  
  127. begin  
  128.   Result := AtomicCmpExchange(Target, Exchange, Comparand);  
  129. end;  
  130.   
  131. function InterlockedCompareExchangePointer(var Target: Pointer; Exchange: Pointer; Comparand: Pointer): Pointer;  
  132. begin  
  133.   Result := AtomicCmpExchange(Target, Exchange, Comparand);  
  134. end;  
  135.   
  136. function InterlockedDecrement(var Addend: Integer): Integer;  
  137. begin  
  138.   Result := AtomicDecrement(Addend);  
  139. end;  
  140.   
  141. function InterlockedExchange(var Target: Integer; Value: Integer): Integer;  
  142. begin  
  143.   Result := AtomicExchange(Target, Value);  
  144. end;  
  145.   
  146. function InterlockedExchangePointer(var Target: Pointer; Value: Pointer): Pointer;  
  147. begin  
  148.   Result := AtomicExchange(Target, Value);  
  149. end;  
  150.   
  151. function InterlockedIncrement(var Addend: Integer): Integer;  
  152. begin  
  153.   Result := AtomicIncrement(Addend);  
  154. end;  
  155.   
  156. {¥ENDIF CPUARM}  

  

机能测试

采取寰宇弦供给的评估法度,进行了一些批改,分别对应用不合的临界区的队列进行对比成果如下:

此中Swith是因队列读空,进行线程高低文切换的次数

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值