相关疑难解决方法(0)

TThreadedQueue不具备多个消费者的能力?

尝试在单个生产者多个消费者方案中使用TThreadedQueue(Generics.Collections).(DELPHI-XE).我们的想法是将对象推入队列,让几个工作线程排空队列.

但它没有按预期工作.当两个或多个工作线程调用PopItem时,将从TThreadedQueue抛出访问冲突.

如果对PopItem的调用是使用临界区序列化的,那么一切都很好.

当然,TThreadedQueue应该能够处理多个消费者,所以我错过了什么或者这是TThreadedQueue中的一个纯粹的错误?

这是一个产生错误的简单示例.

program TestThreadedQueue;

{$APPTYPE CONSOLE}

uses
//  FastMM4 in '..\..\..\FastMM4\FastMM4.pas',
  Windows,
  Messages,
  Classes,
  SysUtils,
  SyncObjs,
  Generics.Collections;

type TThreadTaskMsg =
       class(TObject)
         private
           threadID  : integer;
           threadMsg : string;
         public
           Constructor Create( ID : integer; const msg : string);
       end;

type TThreadReader =
       class(TThread)
         private
           fPopQueue   : TThreadedQueue<TObject>;
           fSync       : TCriticalSection;
           fMsg        : TThreadTaskMsg;
           fException  : Exception;
           procedure DoSync;
           procedure DoHandleException;
         public
           Constructor Create( popQueue : TThreadedQueue<TObject>;
                               sync     : TCriticalSection);
           procedure Execute; override;
       end;

Constructor TThreadReader.Create( popQueue : …
Run Code Online (Sandbox Code Playgroud)

delphi queue delphi-xe delphi-xe2

43
推荐指数
2
解决办法
5994
查看次数

Thread.FreeOnTerminate:= True,内存泄漏和ghost运行

几年前,我决定永远不要仅仅依赖于将线程的FreeOnTerminate属性设置为true以确保其被破坏,因为我在应用程序终止时发现并推理了两件事:

  1. 它会产生内存泄漏,并且
  2. 程序终止后,线程仍然在笔记本键盘下方的某处运行.

我熟悉了一个解决方法,并没有一直困扰我.直到今晚,再次有人(在这种情况下为@MartinJames)评论我的回答,其中我引用了一些不FreeOnTerminate与线程提前终止结合使用的代码.我回到RTL代码中,意识到我可能做出了错误的假设.但我也不太确定,因此这个问题.

首先,为了重现上述陈述,使用了这个说明性代码:

unit Unit3;

interface

uses
  Classes, Windows, Messages, Forms;

type
  TMyThread = class(TThread)
    FForm: TForm;
    procedure Progress;
    procedure Execute; override;
  end;

  TMainForm = class(TForm)
    procedure FormClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FThread: TMyThread;
  end;

implementation

{$R *.dfm}

{ TMyThread }

procedure TMyThread.Execute;
begin
  while not Terminated do
  begin
    Synchronize(Progress);
    Sleep(2000);
  end;
end;

procedure TMyThread.Progress;
begin
  FForm.Caption := FForm.Caption + '.';
end;

{ TMainForm }

procedure TMainForm.FormClick(Sender: TObject);
begin
  FThread := …
Run Code Online (Sandbox Code Playgroud)

delphi multithreading memory-leaks delphi-7

13
推荐指数
1
解决办法
3696
查看次数

何时手动释放线程

如果我从主线程创建(挂起)线程:

  with TMyThread.Create(True) do
  begin
    OnTerminate := ThreadTerminated;
    FreeOnTerminate := False;
    Start;
  end;
Run Code Online (Sandbox Code Playgroud)

一旦完成,我该如何解放该实例?(即执行过程已完成执行 - 假设我已捕获异常).

这种破坏tthread对象链接的正确方法显示了一种方法(通过PostMessage过程),它工作正常并且有意义.但是,如果我创建线程并且我没有表单的句柄或我可以调用PostMessage过程的东西,该怎么办?例如,我在直接来自TObject的类中创建线程?

TMyClass = class
public
  procedure DoSomething;
end;

TMyClass.DoSomething;
begin
      with TMyThread.Create(True) do
      begin
        OnTerminate := ThreadTerminated;
        FreeOnTerminate := False;
        Start;
      end;  
end;
Run Code Online (Sandbox Code Playgroud)

所以,我想,如何在不访问表单句柄的情况下释放一个线程?

谢谢

delphi delphi-xe2

8
推荐指数
1
解决办法
5492
查看次数

Delphi:线程作业的线程列表 - 排队

我有一些基于TThreads的操作.现在我需要创建包含要完成的作业列表的线程,然后在前一个完成后立即触发每个...我应该如何编写它?我不能允许线程同时运行,因为可能有超过10 000个操作要完成.很难找到TEvent和其他同步对象的文档示例......希望我能在这里找到一些帮助......

先谢谢,迈克尔

delphi queue multithreading

4
推荐指数
1
解决办法
5998
查看次数