Multithreading 如何清空OmniThreadLibrary线程池队列?
我刚刚发现了OmniThreadLibrary并开始玩它。我正在尝试启动最多不超过20个任务,并将其余任务发送到队列 我修改了OmniThreadLibrary的00_Beep项目以执行此操作:Multithreading 如何清空OmniThreadLibrary线程池队列?,multithreading,delphi,omnithreadlibrary,Multithreading,Delphi,Omnithreadlibrary,我刚刚发现了OmniThreadLibrary并开始玩它。我正在尝试启动最多不超过20个任务,并将其余任务发送到队列 我修改了OmniThreadLibrary的00_Beep项目以执行此操作: const TASKS_COUNT = 100; procedure TfrmTestSimple.btnBeepClick(Sender: TObject); var I: Integer; begin with OmniEventMonitor do for I
const
TASKS_COUNT = 100;
procedure TfrmTestSimple.btnBeepClick(Sender: TObject);
var
I: Integer;
begin
with OmniEventMonitor do
for I := 1 to TASKS_COUNT do
Monitor(CreateTask(Beep, 'Beep-' + IntToStr(I))).Schedule;
end;
procedure TfrmTestSimple.FormCreate(Sender: TObject);
begin
GlobalOmniThreadPool.MonitorWith(OmniEventMonitor);
GlobalOmniThreadPool.MaxExecuting := 20;
GlobalOmniThreadPool.MaxQueued := 0;
end;
它可以工作,但如果我将任务数(即任务数)增加到7000,我会得到一个例外:
TOmniCommunicationEndpoint.Send:队列已满
我读了我能找到的任何东西(OTL博客和论坛、示例项目、谷歌搜索等等),似乎为了防止这种情况,我必须定期清空队列
所以我尝试了这个,但没有成功:
procedure TfrmTestSimple.OmniEventMonitorTaskTerminated(const task: IOmniTaskControl);
begin
Task.Terminate(1); // I also tried: Task.Terminate(0);
Task.Comm.Reader.Empty; // Task.Comm.OtherEndpoint.Reader.Empty; didn't work either
Task.Comm.Writer.Empty; // Task.Comm.OtherEndpoint.Writer.Empty; didn't work either
end;
有没有关于如何清空队列和避免此异常的建议
我知道有人可能会说队列中有这么多任务是荒谬的,只要告诉我重新设计我的应用程序,这既不是一个假设问题,也不在我的问题范围之内,现在我只需要知道OTL中排队系统的限制以及如何绕过这个限制
提前谢谢 这个表单帖子没有显示如何清空OmniThreadLibrary线程池队列,但是它显示了如何为OmniThreadLibrary创建一个几乎无限的等待队列(这基本上是我的目标):
谢谢你们给我的帮助,你们真是太棒了 这个表单帖子没有显示如何清空OmniThreadLibrary线程池队列,但是它显示了如何为OmniThreadLibrary创建一个几乎无限的等待队列(这基本上是我的目标):
谢谢你们给我的帮助,你们真是太棒了 缩写“AV”表示访问冲突。这真的是你得到的吗?看起来您只是遇到了一个普通的逻辑错误-队列已满,您试图在其中放入更多内容。要清空它,您是要阻止您的程序直到队列中的项目被执行,还是要放弃队列中的项目并继续对新项目进行排队?@Rob:我跟踪了来源,OTL引发了一个异常。理想情况下,我希望队列能够动态扩展自身(我刚刚开始使用OTL,比如24小时,我仍然不完全理解OTL)。简单看一下代码,我发现一个常量“CDefaultQueueSize=1000;”在OTLCOM单元中。“OtlThreadPool:”owtCommChannel:=CreateTwoWayChannel(100,owtTerminateEvent);”中还有一个有趣的调用我找不到任何设置为7000的东西。你应该看看这些限制-一个或多个可能是相关的。您的池中有多少线程?我认为每个池线程可能有一个单独的输入队列(大小为100?)。@Rob:对不起,我应该更明确一些。我最初认为,每当任务完成时,OTL都会从队列中读取下一个任务的信息,启动新任务,然后将其从队列中删除。至少我认为OTL的队列就是这么做的。因此,为了回答您的问题:这两个选项对我都不好,理想情况下,我希望队列能够动态扩展/收缩(即,一旦任务启动,它就会从队列中移除并移动到池中)。但似乎不可能…?请注意,OTL队列是环形缓冲区,可能是为了在推/弹出时避免分配/释放。环形缓冲区的大小在初始化期间设置。缩写“AV”表示访问冲突。这真的是你得到的吗?看起来您只是遇到了一个普通的逻辑错误-队列已满,您试图在其中放入更多内容。要清空它,您是要阻止您的程序直到队列中的项目被执行,还是要放弃队列中的项目并继续对新项目进行排队?@Rob:我跟踪了来源,OTL引发了一个异常。理想情况下,我希望队列能够动态扩展自身(我刚刚开始使用OTL,比如24小时,我仍然不完全理解OTL)。简单看一下代码,我发现一个常量“CDefaultQueueSize=1000;”在OTLCOM单元中。“OtlThreadPool:”owtCommChannel:=CreateTwoWayChannel(100,owtTerminateEvent);”中还有一个有趣的调用我找不到任何设置为7000的东西。你应该看看这些限制-一个或多个可能是相关的。您的池中有多少线程?我认为每个池线程可能有一个单独的输入队列(大小为100?)。@Rob:对不起,我应该更明确一些。我最初认为,每当任务完成时,OTL都会从队列中读取下一个任务的信息,启动新任务,然后将其从队列中删除。至少我认为OTL的队列就是这么做的。因此,为了回答您的问题:这两个选项对我都不好,理想情况下,我希望队列能够动态扩展/收缩(即,一旦任务启动,它就会从队列中移除并移动到池中)。但似乎不可能…?请注意,OTL队列是环形缓冲区,可能是为了在推/弹出时避免分配/释放。环形缓冲区的大小是在初始化过程中设置的。@vavan:整个论坛现在关闭,但您可以使用回程机器读取整个线程:@vavan:整个论坛现在关闭,但您可以使用回程机器读取整个线程: