Delphi 线程循环

落幕年代 2015-10-22 09:13:58
写了3个线程
thread1.thread2.thread3;对实时传进的文本文件进行处理。
如何让3个线程进行循环;实时处理传进来的文本文件。
...全文
429 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
pathletboy 2015-10-23
  • 打赏
  • 举报
回复
希望你能看懂,因为泛型容器在D2009得到支持,你可以用XE系列测试,当然这个只是简单示例,容错部分不一定处理完全,你得看明白意思了后改。
unit TestUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Generics.Collections,
  System.SyncObjs, Vcl.StdCtrls;

type
  TTestForm = class(TForm)
    mmo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TMissionQueue = class
  strict private
    const
      DEFAULT_QUEUE_LENGTH = 100;
  private
    FQueue: TQueue<string>;
    FCri: TCriticalSection;
    FSem: THandle;
  public
    constructor Create(queueLength: Cardinal = DEFAULT_QUEUE_LENGTH);
    destructor Destroy; override;
    procedure Push(const filename: string);
    function Pop(const timeout: Cardinal = INFINITE): string;
  end;

  TWorker = class(TThread)
  protected
    procedure Execute(); override;
  end;

var
  TestForm: TTestForm;
  mq: TMissionQueue;

implementation

{$R *.dfm}
constructor TMissionQueue.Create(queueLength: Cardinal);
begin
  FQueue := TQueue<string>.Create;
  FCri := TCriticalSection.Create;
  FSem := CreateSemaphore(nil, 0, queueLength, nil);
end;

destructor TMissionQueue.Destroy;
begin
  CloseHandle(FSem);
  FCri.Free;
  FQueue.Free;
end;

function TMissionQueue.Pop(const timeout: Cardinal): string;
begin
  Result := '';
  case WaitForSingleObject(FSem, timeout) of
    WAIT_OBJECT_0:
      begin
        FCri.Enter;
        try
          Result := FQueue.Dequeue;
        finally
          FCri.Leave;
        end;
      end;
  end;
end;

procedure TMissionQueue.Push(const filename: string);
begin
  FCri.Enter;
  try
    FQueue.Enqueue(filename);
  finally
    FCri.Leave;
  end;
  ReleaseSemaphore(FSem, 1, nil);
end;


{ TWorker }

procedure TWorker.Execute;
var
  f: string;
begin
  while not Terminated do
  begin
    f := mq.Pop();
    if f = '' then
      Break;
    Synchronize(
      procedure()
      begin
        TestForm.mmo1.Lines.Add('tid:' + IntToStr(ThreadID) + ' processing ' + f)
      end);
    Sleep(Random(3000)); //模拟处理
    Synchronize(
      procedure()
      begin
        TestForm.mmo1.Lines.Add('tid:' + IntToStr(ThreadID) + ' processed ' + f)
      end);
  end;
end;

procedure TTestForm.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  mq := TMissionQueue.Create;
  for i := 1 to 50 do
  begin
    mq.Push('file' + IntToStr(i));   //模拟插入50个待处理的文件名
  end;
  for i := 0 to 2 do
  begin
    TWorker.Create(False);  //创建3个工作线程
  end;

end;

procedure TTestForm.FormDestroy(Sender: TObject);
begin
  mq.Free;
end;

end.
lyhoo163 2015-10-23
  • 打赏
  • 举报
回复
看到懂了你的意图。仅建议,供参考:

1、建立一个函数,处理文本文件;
2、建立一个线程,调用处理文本文件的函数;
3、建立一个队列,三个指针,一个是调用线程;一个是入队列,一个出队列。
这样用一个线程,处理比较好,不会造成干扰。

代码还是自己写吧。
落幕年代 2015-10-23
  • 打赏
  • 举报
回复
引用 5 楼 lyhoo163 的回复:
procedure Thread1.Execute; procedure Thread2.Execute; procedure Thread3.Execute; 大侠;队列等待怎么实现;现在有这3个线程如何写可以加快处理速度;
lyhoo163 2015-10-23
  • 打赏
  • 举报
回复
卡不是处理代码的问题,是你多开线程,每个线程占用CPU的(分配)时间,造成卡。你再多几个线程,还是要卡(等待)处理。 什么情况下,多开线程可以加快速度,当单个线程占用CPU很少时,多个线程占用CPU时间不超过90%时,此时,多线程可以加快处理速度。当线程占用CPU时间达到90%时,多开一个线程,线程会等待分配CPU。此时,多开线程是无效果的(不能加速)。 同时,PC是多核的,速度越快。就能多开线程。但是你要考虑普遍意义。一般PC机的感觉。 因此,我还是建议你检查一下线程,占用CPU多少,适当使用N个线程,让队列等待处理,这样软件(计算机)不会显得很卡(鼠标键盘停滞感)
落幕年代 2015-10-23
  • 打赏
  • 举报
回复
引用 1 楼 pathletboy 的回复:
维护一个队列,然后线程不停的从队列中取任务然后处理。
队列是怎么用的;现在3个线程同时处理有点卡。
落幕年代 2015-10-23
  • 打赏
  • 举报
回复
引用 2 楼 lyhoo163 的回复:
看到懂了你的意图。仅建议,供参考: 1、建立一个函数,处理文本文件; 2、建立一个线程,调用处理文本文件的函数; 3、建立一个队列,三个指针,一个是调用线程;一个是入队列,一个出队列。 这样用一个线程,处理比较好,不会造成干扰。 代码还是自己写吧。
现在3个线程同时处理很卡;怎么建立队列?
pathletboy 2015-10-22
  • 打赏
  • 举报
回复
维护一个队列,然后线程不停的从队列中取任务然后处理。

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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