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