DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: lorangeve
今日帖子: 41
在线用户: 20
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/9/4 2:18:12
标题:
Delphi 为什么没有官方线程池? 浏览:3266
加入我的收藏
楼主: 想实现的功能是

线程池开10线程

单开一条控制线程 检测线程池任务  正在执行3个任务则不提交

如果小于3 则提交任务。

但是官方似乎没有正式的线程池库,只有一个为了实现TTask做的一个线程池【部分功能不完善】

不知道要实现这样的构想  有没有方便的解决方案。
----------------------------------------------
-
作者:
男 tengo (tengo) ★☆☆☆☆ -
盒子活跃会员
2019/9/4 6:56:09
1楼: qdac里边的qwork,多线程很方便。www.qdac.cc
----------------------------------------------
-
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/9/4 13:50:22
2楼: 请教一下,【部分功能不完善】是指啥?
----------------------------------------------
-
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/9/5 19:43:48
3楼: @zwjchinazwj

官方线程池TThread 无法获知  空闲线程数  工作线程数  排队任务数

另外 没有 Wait

据我查的资料是没有啊
----------------------------------------------
-
作者:
男 hnxxcxg (咏南中间件) ★☆☆☆☆ -
盒子活跃会员
2019/9/5 20:36:29
4楼: INDY10的线程池是有源码看的。
----------------------------------------------
中间件QQ群: 92449782 博客: http://www.cnblogs.com/hnxxcxg/
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/9/5 21:54:57
5楼: @hnxxcxg

嗯 我知道。INDY10的。 

自己写当然可以我只是好奇没有现成的
----------------------------------------------
-
作者:
男 chinaz (有缘人) ★☆☆☆☆ -
神秘会员
2019/9/5 22:22:07
6楼: 你可以看看官方的task的实现,见System.Threading.pas
----------------------------------------------
一路风雨走过,因为有你们
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/9/6 6:41:29
7楼: @chencong5025 (Nicosoft)

关于 空闲线程数  工作线程数  排队任务数
IdleWorkerThreadCount QueuedRequestCount WorkerThreadCount

  TThreadPoolStats = record
   ...
  public
    property WorkerThreadCount: Integer read FWorkerThreadCount;
    property IdleWorkerThreadCount: Integer read FIdleWorkerThreadCount;
    property QueuedRequestCount: Integer read FQueuedRequestCount;
  ...
  end;

关于wait:
  ITask = interface(TThreadPool.IThreadPoolWorkItem)
    function Wait(Timeout: Cardinal = INFINITE): Boolean; overload;
    function Wait(const Timeout: TTimeSpan): Boolean; overload;
    ...
  end;

  TTask = class(TAbstractTask, TThreadPool.IThreadPoolWorkItem, ITask, TAbstractTask.IInternalTask)
  ...
    class function WaitForAll(const Tasks: array of ITask): Boolean; overload; static;
    class function WaitForAll(const Tasks: array of ITask; Timeout: Cardinal): Boolean; overload; static;
    class function WaitForAll(const Tasks: array of ITask; const Timeout: TTimeSpan): Boolean; overload; static;
    class function WaitForAny(const Tasks: array of ITask): Integer; overload; static;
    class function WaitForAny(const Tasks: array of ITask; Timeout: Cardinal): Integer; overload; static;
    class function WaitForAny(const Tasks: array of ITask; const Timeout: TTimeSpan): Integer; overload; static;

建议你先好好读下 Threading.pas 单元
----------------------------------------------
-
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/9/6 12:55:51
8楼: @zwjchinazwj (蒲石)

谢谢  关于wait 不希望用task。

不过IdleWorkerThreadCount QueuedRequestCount WorkerThreadCount 我去找找。

谢谢帮助
----------------------------------------------
-
作者:
男 hnxxcxg (咏南中间件) ★☆☆☆☆ -
盒子活跃会员
2019/9/9 8:05:37
9楼: https://www.cnblogs.com/hnxxcxg/p/11080875.html 楼主看看这个
----------------------------------------------
中间件QQ群: 92449782 博客: http://www.cnblogs.com/hnxxcxg/
作者:
男 l_star (l.star) ★☆☆☆☆ -
普通会员
2019/9/9 14:28:31
10楼: hnxxcxg:
涉及4个单元文件:utils_strings.pas,utils_queues.pas,utils_queueTask.pas,utils_grouptask.pas。
有源码?
----------------------------------------------
-
作者:
男 l_star (l.star) ★☆☆☆☆ -
普通会员
2019/9/9 14:29:05
11楼: 看到了,找DIOCP
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2019/9/10 12:07:14
12楼: 所谓的池,就是个 List 嘛。
所谓的线程,就是个对象嘛。

那么,自己写一个有多难?
----------------------------------------------
-
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/9/10 13:41:15
13楼: @pcplayer 

不是自己不会写 我只是好奇 官方居然没有完善的库
----------------------------------------------
-
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/9/10 13:42:09
14楼: @hnxxcxg
不是自己不会写 我只是好奇 官方居然没有完善的库
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2019/9/10 19:11:34
15楼: 我估计就是因为太简单,所以官方没有做一个现成的。

或者说,如果要做一个各种场景都满足的,估计会比较复杂,比较重。所以还是个人按自己需要自己搞好了。
----------------------------------------------
-
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/9/10 20:09:07
16楼: 奇怪了 TThreadPool 不算线程池?
----------------------------------------------
-
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/9/11 9:54:54
17楼: 用Task就是用线程池,这么好用的东西,可以说Task Parallel是新的Delphi中
为数不多的,我觉得非常棒的东西。
----------------------------------------------
-
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/9/11 19:52:13
18楼: @zwjchinazwj

Task Parallel
实现我说的这种需求将变得非常不好用。而传统线程池实现 则很简单。无关好坏只是说使用场景

TThreadPool 我去看过了。相同代码用Qworker没崩 用这个TThreadPool居然报内存分配不足。。没细看了。目前qworker工作正常
----------------------------------------------
-
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/9/11 20:10:02
19楼: 我估计,应该是你思路问题,与场景无关。

例如:“正在执行3个任务则不提交,如果小于3 则提交任务。”

根本不需要检测线程池中工作线程数量.
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2019/9/12 9:15:36
20楼: 楼上说不用检查数量,也对。用类工厂模式。问线程池要空闲线程对象,如果没有就拿不到。当然线程池本身还是要有一个上限数量的设置。这种模式的好处是,外部使用线程池的代码,无需去判断线程池现在有多少个空闲,够用不够用。这些应该是线程池自己搞定的事。外面只需要问它拿空闲对象。这样简化使用,降低耦合。

TTask 只是把某些需要用到线程的场景,代码上简化掉了。它还是个线程。和它类似的东西,很多年以前,就有第三方控件提供同样的功能了。比如 JEDI 那套。

Parallel 是个好东西,很简单地就可以整出并行而且可读性强的代码来。我实际测试过 Parallel,在可以并行处理的地方比如逐个像素处理图片,用了它,确实根据 CPU 内核数量缩短了处理时间,而且代码还简单好懂。
----------------------------------------------
-
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/9/12 10:43:50
21楼: RunnableTaskCount := 3;
while True do
begin
  if RunnableTaskCount > 0 then
  begin 
    TInterlocked.Decrement(RunnableTaskCount );
    TTask.Run
    (
      procedure 
      beign
        //Execute every thing you want.
        TInterlocked.Increment(RunnableTaskCount );
      end
    );
  end;
  Sleep(10);
end;

伪代码,简单,清爽。
----------------------------------------------
-
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/10/12 20:46:21
22楼: @zwjchinazwj

我又N个任务  不定长  有可能100 1000 1W 甚至10W任务。

我需要程序维持稳定的10线程做任务。每个任务我会传不同参数

请问用TTask 如何能方便快捷。

我用线程池获取空闲线程是 为了维持10线程工作。
不要说让我生成10W Task数组哦。。。

另外waitall我记得最大是64把。
----------------------------------------------
-
作者:
男 a07272 (Allen) ★☆☆☆☆ -
盒子活跃会员
2019/10/14 6:43:20
23楼: 如果不介意參考別人寫的,可以看一下
https://bitbucket.org/sivv/cocinasync/src/develop/
如果真要找內建的,哪...可能是殘念,請自行處理
比較早期的版本,哪這個我個人覺得這個是首選
https://www.idefixpack.de/blog/bugfix-units/asynccalls-29-asynchronous-function-calls/
不過如果是要 萬級 的多工,如果大大有找到穩定的元件或方式,請分享,謝謝
----------------------------------------------
-
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/10/14 9:52:23
24楼:   TThreadPool.Current.MinWorkerThreads := 10;

  TotalTaskCount := 99999999;
  RunnableTaskCount := 10;
  while TotalTaskCount > 0 do
  begin
    if RunnableTaskCount > 0 then
    begin
      Dec(TotalTaskCount);

      TInterlocked.Decrement(RunnableTaskCount );
      
      TaskParamDefinedByYourSelf.Param1 := XXXX;
      TaskParamDefinedByYourSelf.Param2 := YYYY;
      //...

      TTask.Run
      (
        procedure
        beign
          //using TaskParamDefinedByYourSelf.Param1 

          //Execute every thing you want.
          TInterlocked.Increment(RunnableTaskCount );
        end
      );
    end;
    Sleep(10);
  end;

兄弟,你的思维太局限。你应该想办法用不同的方法去解决问题,
而不是自己假定只能用一种不合理方式,然后否定它,最后结论就变成不可用。
比如,你假设的10w Task数组,如果你好好看了并理解之前我给的代码,
你这个问题根本就不该问,之前的代码,控制3个任务同时运行根本没有使用
Task数组,也没有使用wait
----------------------------------------------
-
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/10/14 15:51:40
25楼: @zwjchinazwj

我没有否定它  

我只是说 用TTask如何使用 类似这种场景

我遍寻资料 总感觉我的用法不对

我是虚心请教
----------------------------------------------
-
作者:
男 fausten (fausten) ★☆☆☆☆ -
盒子活跃会员
2019/10/14 16:47:52
26楼: 这些都没有linux下的进程机制好,我用freepascal结合php的多进程机制用的很好
----------------------------------------------
-
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/10/14 17:50:43
27楼: 使用Wait的代码,可以如下:
const
  MAX_RUNNING_COUNT = 10;
var
  Tasks: array[0..MAX_RUNNING_COUNT - 1] of ITask;
  FinishedIdx, i: Integer;
begin
  TThreadPool.Current.MinWorkerThreads := 10;

  for i := 0 to MAX_RUNNING_COUNT - 1 do
  begin
    //TTask.WaitForAny 不能提交nil Task,因此这里创建10个空任务
    Tasks[i] := TTask.Run(procedure begin end);
  end;

  while True do
  begin
    FinishedIdx := TTask.WaitForAny(Tasks, 200);
    if FinishedIdx >= 0 then
    begin
      Tasks[FinishedIdx] := TTask.Run
          (
          //Execute every thing you want.
          );
    end
  end;
end;
----------------------------------------------
-
作者:
男 chencong5025 (Nicosoft) ▲▲▲△△ -
普通会员
2019/10/14 22:43:19
28楼: @zwjchinazwj

谢谢指点。

Task能否传递类似函数指针的参数呢?

就是 TTask.Run
          (
          //Execute every thing you want.
          );

这个任务逻辑代码 可以用其他function 来分离出来。不然每次都得写。
----------------------------------------------
-
作者:
男 zwjchinazwj (蒲石) ★☆☆☆☆ -
普通会员
2019/10/14 22:52:04
29楼: 你自己思考尝试吧,你需要自己去学习摸索。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行93.75毫秒 RSS