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

转载 2017年03月23日 08:06:34

本文供给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是因队列读空,进行线程高低文切换的次数

delphi非常简单的线程安全队列

在开发项目中,经常会遇到多线程操作,此时肯定需要一个线程安全的队列,我一直在用这个,是大牛写的 unit MyQueue; interface {$DEFINE ...
  • y281252548
  • y281252548
  • 2016年01月28日 13:45
  • 2351

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

本文供给Delphi一个基于原子操纵的无锁队列,简略单纯高效。实用于多线程大吞吐量操纵的队列。 科学是使人精力变得大胆的最好路子。可用于Android体系和32,64位Windows体系。 ...
  • rocklee
  • rocklee
  • 2015年09月29日 10:50
  • 1617

Delphi下MSMQ(Mircosoft Message Queue)实例(私有队列)

 网上关于消息队列技术原理说明的详细文档很多,但涉及到Delphi的具体实现很少,这是我从网上找了一上午的资料,自己整合和尝试的能运行的程序。打开控制面板->程序->添加组件,添加消息队列打开控制面板...
  • houhu_cs
  • houhu_cs
  • 2010年02月21日 17:04
  • 3296

delphi编写的高速队列类

  • 2013年12月06日 16:32
  • 4KB
  • 下载

delphi中关于队列的使用QUEUE

  • 2013年03月28日 17:32
  • 167KB
  • 下载

DIOCP开源项目-Delphi高性能无锁队列(lock-free)

http://www.cnblogs.com/DKSoft/p/3722382.html
  • l799623787
  • l799623787
  • 2014年05月23日 19:50
  • 1064

delphi 中TObjectQueue使用注意点

TObjectQueue 开始使用的时候都要创建一个对象objQueue1,但是delphi中,对象其实都类似VC++中的指针, 所以如果你来一个objQueue2 := objQueue1 这...
  • youxiazzz12
  • youxiazzz12
  • 2012年09月03日 15:02
  • 2754

Delphi版 环形无锁缓冲

{*******************************************************} { ...
  • wowlancelot
  • wowlancelot
  • 2016年04月13日 23:33
  • 238

一个队列类的实现(比delphi自带的速度快70倍)

测试结果   实现的代码   unit sfContnrs; interface {$DEFINE MULTI_THREAD_QUEUE} //线程安全版本...
  • caonumber
  • caonumber
  • 2015年10月06日 11:43
  • 301

delphi 队列实例

  • 2010年11月27日 11:03
  • 169KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:简略单纯高效的Delphi原子队列
举报原因:
原因补充:

(最多只允许输入30个字)