本文供给Delphi一个基于原子操纵的无锁队列,简略单纯高效。实用于多线程大吞吐量操纵的队列。
科学是使人精力变得大胆的最好路子。可用于Android体系和32,64位Windows体系。
感激歼10和qsl供给了批改建议!
有如下题目:
1.必须实现开辟内存
2.队列大小必须是2的幂
3.不克不及压入空指针
unit utAtomFIFO; interface Uses SysUtils, SyncObjs; Type TAtomFIFO = Class Protected FWritePtr: Integer; FReadPtr: Integer; FCount:Integer; FHighBound:Integer; FisEmpty:Integer; FData: array of Pointer; function GetSize:Integer; Public procedure Push(Item: Pointer); function Pop: Pointer; Constructor Create(Size: Integer); Virtual; Destructor Destroy; Override; Procedure Empty; property Size: Integer read GetSize; property UsedCount:Integer read FCount; End; Implementation {¥I InterlockedAPIs.inc} //创建队列,大小必须是2的幂,须要开辟足够大的队列,防止队列溢出 Constructor TAtomFIFO.Create(Size: Integer); var i:NativeInt; OK:Boolean; Begin Inherited Create; OK:=(Size and (Size-1)=0); if not OK then raise Exception.Create(""FIFO长度必须大于便是256并为2的幂""); try SetLength(FData, Size); FHighBound:=Size-1; except Raise Exception.Create(""FIFO申请内存失败""); end; End; Destructor TAtomFIFO.Destroy; Begin SetLength(FData, 0); Inherited; End; procedure TAtomFIFO.Empty; begin while (InterlockedExchange(FReadPtr, 0)<>0) and (InterlockedExchange(FWritePtr, 0)<>0) and (InterlockedExchange(FCount, 0)<>0) do; end; function TAtomFIFO.GetSize: Integer; begin Result:=FHighBound+1; end; procedure TAtomFIFO.Push(Item:Pointer); var N:Integer; begin if Item=nil then Exit; N:=InterlockedIncrement(FWritePtr) and FHighBound; FData[N]:=Item; InterlockedIncrement(FCount); end; Function TAtomFIFO.Pop:Pointer; var N:Integer; begin if InterlockedDecrement(FCount)<0 then begin InterlockedIncrement(FCount); Result:=nil; end else begin N:=InterlockedIncrement(FReadPtr) and FHighBound; while FData[N]=nil do Sleep(1); Result:=FData[N]; FData[N]:=nil; end; end; End.
InterlockedAPIs.inc
{*******************************************************} { } { CodeGear Delphi Runtime Library } { } { copyright(c) 1995-2014 Embarcadero Technologies, Inc. } { } {*******************************************************} {¥IFDEF cpuX86} function InterlockedAdd(var Addend: Integer; Increment: Integer): Integer; asm MOV ECX,EAX MOV EAX,EDX LOCK XADD [ECX],EAX ADD EAX,EDX end; function InterlockedCompareExchange(var Target: Integer; Exchange: Integer; Comparand: Integer): Integer; asm XCHG EAX,ECX LOCK CMPXCHG [ECX],EDX end; function InterlockedCompareExchangePointer(var Target: Pointer; Exchange: Pointer; Comparand: Pointer): Pointer; asm JMP InterlockedCompareExchange end; function InterlockedDecrement(var Addend: Integer): Integer; asm MOV EDX,-1 JMP InterlockedAdd end; function InterlockedExchange(var Target: Integer; Value: Integer): Integer; asm MOV ECX,EAX MOV EAX,[ECX] @@loop: LOCK CMPXCHG [ECX],EDX JNZ @@loop end; function InterlockedExchangePointer(var Target: Pointer; Value: Pointer): Pointer; asm JMP InterlockedExchange end; function InterlockedIncrement(var Addend: Integer): Integer; asm MOV EDX,1 JMP InterlockedAdd end; {¥ENDIF cpuX86} {¥IFDEF cpuX64} function InterlockedExchangeAdd(var Addend: Integer; Value: Integer): Integer; asm .NOFRAME MOV EAX,EDX LOCK XADD [RCX].Integer,EAX end; function InterlockedDecrement(var Addend: LongInt): LongInt; asm .NOFRAME MOV EAX,-1 LOCK XADD [RCX].Integer,EAX DEC EAX end; function InterlockedIncrement(var Addend: LongInt): LongInt; asm MOV EAX,1 LOCK XADD [RCX].Integer,EAX INC EAX end; function InterlockedCompareExchange(var Destination: Integer; Exchange: Integer; Comparand: Integer): Integer; asm .NOFRAME MOV EAX,R8d LOCK CMPXCHG [RCX].Integer,EDX end; function InterlockedCompareExchange64(var Destination: Int64; Exchange: Int64; Comparand: Int64): Int64; overload; asm .NOFRAME MOV RAX,R8 LOCK CMPXCHG [RCX],RDX end; function InterlockedCompareExchangePointer(var Destination: Pointer; Exchange: Pointer; Comparand: Pointer): Pointer; asm .NOFRAME MOV RAX,R8 LOCK CMPXCHG [RCX],RDX end; function InterlockedExchangePointer(var Target: Pointer; Value: Pointer): Pointer; asm .NOFRAME LOCK XCHG [RCX],RDX MOV RAX,RDX end; function InterlockedExchange(var Target: Integer; Value: Integer): Integer;// inline; asm .NOFRAME LOCK XCHG [RCX],EDX MOV EAX,EDX end; {¥ENDIF cpuX64} {¥IFDEF cpuARM} function InterlockedAdd(var Addend: Integer; Increment: Integer): Integer; begin Result := AtomicIncrement(Addend, Increment); end; function InterlockedCompareExchange(var Target: Integer; Exchange: Integer; Comparand: Integer): Integer; begin Result := AtomicCmpExchange(Target, Exchange, Comparand); end; function InterlockedCompareExchangePointer(var Target: Pointer; Exchange: Pointer; Comparand: Pointer): Pointer; begin Result := AtomicCmpExchange(Target, Exchange, Comparand); end; function InterlockedDecrement(var Addend: Integer): Integer; begin Result := AtomicDecrement(Addend); end; function InterlockedExchange(var Target: Integer; Value: Integer): Integer; begin Result := AtomicExchange(Target, Value); end; function InterlockedExchangePointer(var Target: Pointer; Value: Pointer): Pointer; begin Result := AtomicExchange(Target, Value); end; function InterlockedIncrement(var Addend: Integer): Integer; begin Result := AtomicIncrement(Addend); end; {¥ENDIF cpuARM}
机能测试:
采取寰宇弦供给的评估法度,进行了一些批改,分别对应用不合的临界区的队列进行对比成果如下:
此中Swith是因队列读空,进行线程高低文切换的次数
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。