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