delphi非常简单的线程安全队列

delphi⾮常简单的线程安全队列在开发项⽬中,经常会遇到多线程操作,此时肯定需要⼀个线程安全的队列,我⼀直在⽤这个,是⼤⽜写的
unit MyQueue;
interface
{$DEFINE MULTI_THREAD_QUEUE} //线程安全版本,如果不需要线程安全,请注释掉此⾏代码
{$IFDEF MULTI_THREAD_QUEUE}
uses
Windows;
{$ENDIF}
type
TsfQueue=class
private
FCapacity:Integer;
FTmpBuff:Pointer;
FBuff:pointer;
FPosition:Integer;
{$IFDEF MULTI_THREAD_QUEUE}
FCS:TRTLCriticalSection;
{$ENDIF}
//\\
FPushIndex:Integer;
FPopIndex:Integer;
procedure Lock();
procedure UnLock();
procedure Inernal_SetCapacity(const Value:Integer);
//\\
procedure setCapacity(const Value: Integer);
function getCapacity: Integer;
function getCurCount: Integer;
public
constructor Create(InitCapacity: Integer=1024);
destructor  Destroy();override;
//\\
function Push(AItem: Pointer): Pointer;
function Pop(): Pointer;
public
property Capacity:Integer read getCapacity write setCapacity;
property Count: Integer read getCurCount ;
end;
implementation
{ TsfQueue }
constructor TsfQueue.Create(InitCapacity:Integer);
begin
{$IFDEF MULTI_THREAD_QUEUE}
InitializeCriticalSection(FCS);
{$ENDIF}
if InitCapacity < 1024 then InitCapacity := 1024;
Inernal_SetCapacity(InitCapacity);
end;
destructor TsfQueue.Destroy;
begin
FreeMem(FBuff);
if FTmpBuff <> nil then
FreeMem(FTmpBuff);
//\\
{$IFDEF MULTI_THREAD_QUEUE}
DeleteCriticalSection(FCS);
{$ENDIF}
inherited;
end;
procedure TsfQueue.Lock;
begin
{$IFDEF MULTI_THREAD_QUEUE}
EnterCriticalSection(FCS);
{$ENDIF}
end;
procedure TsfQueue.UnLock;
begin
{$IFDEF MULTI_THREAD_QUEUE}
LeaveCriticalSection(FCS);
{$ENDIF}
end;
procedure TsfQueue.Inernal_SetCapacity(const Value: Integer); var
PageCount,ASize:Integer;
begin
if Value > FCapacity then
begin
if FTmpBuff <> nil then
FreeMem(FTmpBuff);
//扩容
ASize := Value * 4;//计算出所需要的字节数量
Pagecount := ASize div 4096;
if (ASize mod 4096) > 0 then Inc(PageCount);
//转移数据
GetMem(FTmpBuff,PageCount * 4096);
FillChar(FTmpBuff^,PageCount * 4096,#0);
if FBuff <> nil then
begin
Move(FBuff^,FTmpBuff^,FCapacity * 4);
FreeMem(FBuff);
end;
FBuff := FTmpBuff;
//计算新的容量
FCapacity := (PageCount * 4096) div 4;
if FCapacity >= 2048 then
begin
e. coli//FTmpBuff 分配⽤于Pop时候,移动内存
GetMem(FTmpBuff,PageCount * 4096);
end
else
FTmpBuff := nil;
end;
end;
function TsfQueue.Pop: Pointer;
procedure AdjuestMem();
var
pSrc:PInteger;
pTmp:Pointer;
begin
FillChar(FTmpBuff^,FCapacity * 4,#0);
pSrc := PInteger(FBuff);
Inc(pSrc,FPopIndex);
Move(pSrc^,FTmpBuff^,(FCapacity - FPopIndex) * 4);    //\\
//交换指针
pTmp    := FBuff;
FBuff  := FTmpBuff;
FTmpBuff := pTmp;
end;
const
_MoveRange_ = 2048;
var
P:PInteger;
begin
Lock();
try
Result := nil;
if (FPopIndex = FPushIndex) then
Exit;
P := PInteger(FBuff);
Inc(P,FPopIndex);
Result := Pointer(P^);
Inc(FPopIndex);
//队列底部空余内存达到 8192 整体搬迁
if FPopIndex = _MoveRange_ then
begin
AdjuestMem();
FPopIndex := 0;
Dec(FPushIndex,_MoveRange_);
end;
finally
UnLock();
end;钢支撑
end;
function TsfQueue.Push(AItem: Pointer): Pointer;
var
P:PInteger;
begin
Lock();
try
P := PInteger(FBuff);
Inc(P,FPushIndex);
P^ := Integer(AItem);
管理评论
Inc(FPushIndex);
if FPushIndex >= FCapacity then
begin
人机界面设计
/
/扩容加 1024 个位置
Inernal_SetCapacity(FCapacity + 1024);
end;
finally
UnLock();
end;
end;
procedure TsfQueue.setCapacity(const Value: Integer); begin
Lock();
Inernal_SetCapacity(Value);
finally
UnLock();
end;
end;
Capacity: Integer; begin
Lock();
try
Result := Self.FCapacity;
finally玛坤丝
镜泊湖的黄昏UnLock();
end;
end;
CurCount: Integer; begin
Result := FPushIndex - FPopIndex; end;
end.

本文发布于:2024-09-23 03:22:01,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/435854.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:需要   线程   队列   内存   达到   计算   时候   字节
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议