换个标题吧--delphi多线程并发访问无锁队列怎么实现

bbc9527 2013-06-07 12:42:45
http://bbs.csdn.net/topics/390482498
这个帖子 已经大致的说明了问题
经过几天的思考和奋战
我找到了一个可行的解决方法
多线程并发访问无锁队列
但是不知道在delphi里面 怎么实现
代码可以参考里面的代码
流程我大概的重写一下
创建线程A
1、从队列中获得的M(第一次为0,后面为线程B中获得)
2、判断(线程B是否启动)
3、没有启动 则启动线程B
4、执行动作A(M) ----消费这个数据消费完之后才允许它改变
5、执行动作B(inc(事物C)) 消费
6、回到1 直到线程A退出
创建线程B
1、判断是否存在(事物C)
2、不存在则创建(事物C) 生产
3、M=得到变量(事物C)----------- 不断生产这个 数据 并且给A进程消费把这次产生的数据M存到队列里面
4、执行动作B(inc(事物C)) 消费
5、回到1 直到线程B退出
这样的话只要解决队列的问题就可以解决之前的数据覆盖和等待的问题
但是。。delphi里面怎么定义这个东西多线程并发访问无锁队列
论坛貌似不方便发代码 这个地方可以下代码
http://bbs.pediy.com/showthread.php?t=173091
...全文
445 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
bbc9527 2013-06-08
  • 打赏
  • 举报
回复
已经搞定不用这么麻烦 简单就可以解决了
sololie 2013-06-07
  • 打赏
  • 举报
回复
伤脑筋,撸过一顶
bbc9527 2013-06-07
  • 打赏
  • 举报
回复
http://bbs.pediy.com/showthread.php?p=1185887#post1185887 帮忙看下代码 有什么问题谢谢了 这个是文件地址
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 const
   ceshi=10;
type
  TForm1 = class(TForm)
    btn1: TButton;
    btn2: TButton;
    mmo1: TMemo;
    mmo2: TMemo;
    btn3: TButton;
    btn4: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btn3Click(Sender: TObject);
    procedure btn1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
    procedure btn4Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  //缓冲区对象,包含同步句柄和缓冲区
  PDb = ^TDb;
  TDB = class
  private
    FCap: integer;
    Flist: TList;
    FSycHandle: Thandle;
  public
    constructor Create(const pCap: Integer);overload;
  public
    FItemCount: integer;                                                        //测试适用
    destructor Destroy; override;
    function IsEmpty: Boolean;
    function IsFULL: Boolean;
    function Pop: Pointer;
    procedure Push(const pObect: pointer);
    property SycHandle: Thandle read FSycHandle;
  end;
type
  TDBB = class
  private
    //读取缓冲区临界区
    //FPopCritical: TRTLCriticalSection;
    //写入缓冲区临界区
    //FPushCritical: TRTLCriticalSection;
    FBufferA: TDB;
    FbufferB: TDB;
    FPushA: PDB;
    FPushB: PDB;
    FPopA: PDB;
    FPopB: PDB;
    function ChangeBuffer(const pQueueBuffer: PDb): pDb;

  public
    constructor Create(const pCap: Integer);overload;
    destructor Destroy; override;
    function Popup: Pointer;
    function Push(const pObject: pointer): Boolean;
    //
    procedure Flush;
    //获得缓冲区元素数
    function GetALLCount: Integer;
    //缓冲区是否为空
    function ISEmpty: Boolean;

  end;
type 
  Tshiwu=packed record
    c:Integer;
    m:Integer;
    end;
type
  Tthread3 = class(Tthread)
  protected
  procedure Execute;override;
  end;


 
type
  Tthread5 = class(Tthread)
  protected
  procedure Execute;override;
   end;

var
  Form1: TForm1;
  bcunzai:Boolean;
  astopnow:Boolean;
  autoattnow:Boolean;
  xiaofeione:Tthread3;
  xiaofeitwo:Tthread5;
  shiwuc:Tshiwu;
  dq:TDBB;
implementation

{$R *.dfm}
constructor TDB.Create(const pCap: Integer);
begin
  inherited create;
  FCap := pCap;
  FItemCount := 0;
  FSycHandle := CreateEvent(nil, false, false, nil);
  Flist := TList.Create;
end;

destructor TDB.Destroy;
begin
  Flist.Clear;
  Flist.Free;
  CloseHandle(FSycHandle);
  inherited;
end;

function TDB.IsEmpty: Boolean;
begin
  Result := Flist.Count = 0;
end;

function TDB.IsFULL: Boolean;
begin
  Result := Flist.count >= FCap;
  if result then
  begin
    FItemCount := 10;
  end;
end;

function TDB.Pop: Pointer;
begin
  if Flist.Count = 0 then
  begin
    result := nil;
    exit;
  end;
  Result := Flist.Items[0];
  Flist.Delete(0);
  dec(FItemCount);
end;

procedure TDB.Push(const pObect: pointer);
begin
  Flist.Add(pObect);
  inc(FItemCount)
end;

constructor TDBB.Create(const pCap: Integer);
begin
  inherited Create;
  FBufferA := TDB.Create(pCap);
  FBufferB := TDB.Create(pCap);
  FPushA := @FBufferA;
  FPushB := @FbufferB;
  FPopA := @FBufferA;
  FPopB := @FbufferB;
  //InitializeCriticalSection(FPopCritical);
  //InitializeCriticalSection(FPushCritical);
end;

function TDBB.Popup: Pointer;
begin
  //EnterCriticalSection(FPopCritical);
  //try
  if FPopA.IsEmpty then
  begin
    //释放当前读取缓冲区
    SetEvent(FPopA.SycHandle);
    //form1.mmo1.Lines.Add('通知  ::' + inttostr(integer(FPopA)) + ':' + inttostr(FPopA.SycHandle));
    // 得到当前读取缓冲区
    FPopB := ChangeBuffer(FPopA);
    //form1.mmo1.Lines.Add('Pop  ::' + inttostr(integer(FPopB)) + ':' + inttostr(FPopB.SycHandle));
    //接管当前读取缓冲区的拥有权
    WaitForSingleObject(FPopB.SycHandle, INFINITE);
    // 接管读取缓冲区
    FPopA := FPopB;
  end;
  result := FPopA.Pop;
  //finally
  //  LeaveCriticalSection(FPopCritical);
  //end;
end;

function TDBB.Push(const pObject: pointer): Boolean;

begin
  //EnterCriticalSection(FPushCritical);
  //try
  if FPushB.IsFULL then
  begin
    //释放当前写入缓冲区
    SetEvent(FPushB.SycHandle);
    //form1.Memo1.Lines.Add('通知 ::' + inttostr(integer(FPushb)) + ':' + inttostr(FPushb.SycHandle));
    //得到当前写入取缓冲区
    FPushA := ChangeBuffer(FPushB);
    //form1.Memo1.Lines.Add('Push ::' + inttostr(integer(FPusha)) + ':' + inttostr(FPusha.SycHandle));
    //接管当前写入缓冲区的拥有权
    WaitForSingleObject(FPushA.SycHandle, INFINITE);
    //接管写入缓冲区
    FPushB := FPushA;
  end;
  FPushB.Push(pObject);
  result := true;
  //finally
  //  LeaveCriticalSection(FPushCritical);
  //end;
end;

destructor TDBB.Destroy;
begin
  FBufferA.Free;
  FBufferB.Free;
  //DeleteCriticalSection(FPopCritical);
  //DeleteCriticalSection(FPushCritical);
  inherited;
end;

function TDBB.ChangeBuffer(const pQueueBuffer: PDb): pDb;
begin
  if pQueueBuffer = @FBufferA then
  begin
    result := @FBufferB;
  end;
  if pQueueBuffer = @FBufferB then
  begin
    result := @FBufferA;
  end;
end;

procedure TDBB.Flush;
begin
  SetEvent(FBufferA.SycHandle);
  SetEvent(FBufferB.SycHandle);
end;

function TDBB.GetALLCount: Integer;
begin
  Result := FBufferA.FItemCount + FBufferA.FItemCount;
end;

function TDBB.ISEmpty: Boolean;
begin
  Result := FBufferA.IsEmpty and FBufferB.IsEmpty;
end;


procedure eat(var shiwucm:integer);
//var
  begin
    Randomize;
    if shiwucm=0 then
    begin
       shiwucm:=0;
       Form1.mmo1.lines.add('事物m被消费:目前剩余'+inttostr(shiwucm));
    end else
    begin
       shiwucm:=shiwucm-random(10);
       Form1.mmo1.lines.add('事物m被消费:目前剩余'+inttostr(shiwucm));
       if (shiwucm<0) or (shiwucm=0)then
       begin
          shiwucm:=0;
        Form1.mmo1.lines.add('事物m被消费:目前剩余0');
       end;
    end;


  end;

procedure jianshao(var shiwucc:integer);
//var
  begin
    Randomize;
    if shiwucc=0 then
    begin
       shiwucc:=0;
    end else
    begin
       shiwucc:=shiwucc-random(10)-15;
       Form1.mmo2.lines.add('事物c被消费:目前剩余'+inttostr(shiwucc));
       if (shiwucc<0) or (shiwucc=0)then
       begin
          shiwucc:=0;
          Form1.mmo2.lines.add('事物c被消费:目前剩余0');
       end;
    end;


  end;

procedure Tthread3.Execute;

begin

  

 //repeat

    //dq.Create();

 repeat
      if (shiwuc.m<>0)then
      begin
      eat(shiwuc.m);  //消费物品一
      end else
      begin
        if dq.ISEmpty()=False then    //这里判断队列是否为空
        begin
        shiwuc.m:=integer(dq.Popup()); //这里清理队列
        end;


      end;
     if bcunzai=false then
     begin
      xiaofeitwo:=Tthread5.Create(False);
     end;


      Sleep(50);



      jianshao(shiwuc.c);



  
   Sleep(400);
 until astopnow=False;//

  //  dq.Destroy;
  //end;
end;


procedure Tthread5.Execute;

begin
       bcunzai:=True;
       autoattnow:=true;
       Randomize;

       repeat
       Sleep(150);
      // shiwuctwo:=quanjushiwuc;
       if  shiwuc.c=0 then  //这里C消费消费完毕之后 重新生产 但是会产生冲突 如果两个都消费完就没冲突 如果两个都消费完这样无效率
       begin
          shiwuc.m:=50+random(50);
          shiwuc.c:=430+random(30);
          dq.Push(@shiwuc.m);  //这里把数据加入队列
          Form1.mmo2.lines.add('事物m产生:'+inttostr(shiwuc.m));
          Form1.mmo2.lines.add('事物c产生:'+inttostr(shiwuc.c));
       end;

       jianshao(shiwuc.c);
        Sleep(300);
      until autoattnow=False;


end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 bcunzai:=False;
 astopnow:=true;
shiwuc.m:=0;
shiwuc.c:=0;
 autoattnow:=False;
 //dq.Create();
 
end;


procedure TForm1.btn3Click(Sender: TObject);
begin
    astopnow:=False;
    xiaofeione.Suspend;
    xiaofeione.DoTerminate;
   // dq.Destroy;
end;

procedure TForm1.btn1Click(Sender: TObject);
begin

  xiaofeione:=Tthread3.Create(False);
end;

procedure TForm1.btn2Click(Sender: TObject);
begin
  xiaofeitwo:=Tthread5.Create(False);
end;

procedure TForm1.btn4Click(Sender: TObject);
begin
   autoattnow:=False;
   xiaofeitwo.Suspend;
   xiaofeitwo.DoTerminate;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  //dq.Destroy;
end;

end.
这个是代码 pas 的 好心的帮看下
yunsuifeng2009 2013-06-07
  • 打赏
  • 举报
回复
我是来帮楼主顶贴的。我还没有用到这个邮件,但是以后应该会用到。
内容概要:本文围绕水陆两栖无人机的任务规划与执行问题,提出了一种基于Matlab实现的智能路径规划解决方案,重点融合粒子群优化算法(PSO)与遗传算法(GA)进行三维环境下的避障路径规划。研究系统性地构建了从复杂地形建模、任务需求分析到算法设计与仿真实验的完整流程,实现了在多约束、动态障碍物等复杂环境下无人机的高效任务调度。通过对GA与PSO两种智能优化算法在路径长度、收敛速度、路径平滑度及稳定性等方面的对比分析,深入探讨了各自在无人机路径规划中的适用场景与性能差异,验证了所提方法在提升任务执行效率与安全性方面的有效性。该方案不仅适用于水陆交互通用场景,也为多模态无人系统自主导航提供了可扩展的技术框架。; 适合人群:具备一定Matlab编程能力和算法基础,从事无人机路径规划、智能优化算法研究、自动化控制或相关领域科研工作的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于水陆两栖无人机在复杂自然环境(如江河湖海与陆地交错区域)中的自主巡航与任务执行;②比较遗传算法与粒子群算法在三维动态路径规划中的优化性能,指导实际工程中算法选型;③为多约束条件下无人系统的自主决策与实时避障提供算法支持与仿真验证平台。; 阅读建议:建议读者结合提供的Matlab代码进行动手实践,重点关注两种算法的数学建模过程、适应度函数设计、参数调优策略及路径生成逻辑,通过仿真实验直观对比算法性能差异,深入理解智能优化算法在复杂路径规划问题中的应用机制与优化潜力。

16,741

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧