简略单纯高效的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 ...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

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

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

delphi 中TObjectQueue使用注意点

TObjectQueue 开始使用的时候都要创建一个对象objQueue1,但是delphi中,对象其实都类似VC++中的指针, 所以如果你来一个objQueue2 := objQueue1 这...

delphi之IOCP学习(一)

delphi之IOCP学习(一)    困扰已久的网络通信(IOCP:完成端口),今天终于揭开她的神秘面纱了,之前百度N久还是未能理解IOCP,网络上好多博文都没有贴出源码,初学者很难正在理...

JMS消息机制--发布-订阅模式

前面一张文章中我已经写过关于JMS消息机制的PTP(点对点)模式,今天我来写一下我个人对于JMS消息机制的发布-订阅模式。 在看是正文前,我想向大家阐述一下关于PTP与发布-订阅的特点和区别。 特...

HDU3415---单纯的单调队列

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3415 给你一个可循环的数列,1——n 然后给你一个数字k ‘要你求出长度不大于k的最大子串和 ...
  • dr5459
  • dr5459
  • 2013年05月15日 20:51
  • 611

DELPHI的原子世界

  • 2011年04月10日 13:49
  • 173KB
  • 下载

DELPHI的原子世界

  • 2008年12月25日 14:30
  • 108KB
  • 下载

平台无关的高效原子操作:ACE_Atomic_Op

在软件开发中,我们经常会遇到多个线程对同一数据操作的同步问题,如果需要同步保护的是一组变量,则直接分用互斥锁进行保护,可以如果需要保护的只是一个整数(如:int,long...),则有更为高效的办法:...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:简略单纯高效的Delphi原子队列
举报原因:
原因补充:

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