简易高效的Delphi原子队列
本文提供Delphi一个基于原子操作的无锁队列,简易高效。适用于多线程大吞吐量操作的队列。
可用于Android系统和32,64位Windows系统。
感谢歼10和qsl提供了修改建议!
有如下问题:
1.必须实现开辟内存
2.队列大小必须是2的幂
3.不能压入空指针
4.本程序还未经过工程应用考验

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
|
<em id="__mceDel"> </em> |