导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
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
----------------------------------------------
-
作者:
2019/9/4 13:50:22
2楼:
请教一下,【部分功能不完善】是指啥?
----------------------------------------------
-
作者:
2019/9/5 19:43:48
3楼:
@zwjchinazwj 官方线程池TThread 无法获知 空闲线程数 工作线程数 排队任务数 另外 没有 Wait 据我查的资料是没有啊
----------------------------------------------
-
作者:
2019/9/5 20:36:29
4楼:
INDY10的线程池是有源码看的。
----------------------------------------------
中间件QQ群: 92449782 博客: http://www.cnblogs.com/hnxxcxg/
作者:
2019/9/5 21:54:57
5楼:
@hnxxcxg 嗯 我知道。INDY10的。 自己写当然可以我只是好奇没有现成的
----------------------------------------------
-
作者:
2019/9/5 22:22:07
6楼:
你可以看看官方的task的实现,见System.Threading.pas
----------------------------------------------
一路风雨走过,因为有你们
作者:
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 单元
----------------------------------------------
-
作者:
2019/9/6 12:55:51
8楼:
@zwjchinazwj (蒲石) 谢谢 关于wait 不希望用task。 不过IdleWorkerThreadCount QueuedRequestCount WorkerThreadCount 我去找找。 谢谢帮助
----------------------------------------------
-
作者:
2019/9/9 8:05:37
9楼:
https://www.cnblogs.com/hnxxcxg/p/11080875.html 楼主看看这个
----------------------------------------------
中间件QQ群: 92449782 博客: http://www.cnblogs.com/hnxxcxg/
作者:
2019/9/9 14:28:31
10楼:
hnxxcxg: 涉及4个单元文件:utils_strings.pas,utils_queues.pas,utils_queueTask.pas,utils_grouptask.pas。 有源码?
----------------------------------------------
-
作者:
2019/9/9 14:29:05
11楼:
看到了,找DIOCP
----------------------------------------------
-
作者:
2019/9/10 12:07:14
12楼:
所谓的池,就是个 List 嘛。 所谓的线程,就是个对象嘛。 那么,自己写一个有多难?
----------------------------------------------
-
作者:
2019/9/10 13:41:15
13楼:
@pcplayer 不是自己不会写 我只是好奇 官方居然没有完善的库
----------------------------------------------
-
作者:
2019/9/10 13:42:09
14楼:
@hnxxcxg 不是自己不会写 我只是好奇 官方居然没有完善的库
----------------------------------------------
-
作者:
2019/9/10 19:11:34
15楼:
我估计就是因为太简单,所以官方没有做一个现成的。 或者说,如果要做一个各种场景都满足的,估计会比较复杂,比较重。所以还是个人按自己需要自己搞好了。
----------------------------------------------
-
作者:
2019/9/10 20:09:07
16楼:
奇怪了 TThreadPool 不算线程池?
----------------------------------------------
-
作者:
2019/9/11 9:54:54
17楼:
用Task就是用线程池,这么好用的东西,可以说Task Parallel是新的Delphi中 为数不多的,我觉得非常棒的东西。
----------------------------------------------
-
作者:
2019/9/11 19:52:13
18楼:
@zwjchinazwj Task Parallel 实现我说的这种需求将变得非常不好用。而传统线程池实现 则很简单。无关好坏只是说使用场景 TThreadPool 我去看过了。相同代码用Qworker没崩 用这个TThreadPool居然报内存分配不足。。没细看了。目前qworker工作正常
----------------------------------------------
-
作者:
2019/9/11 20:10:02
19楼:
我估计,应该是你思路问题,与场景无关。 例如:“正在执行3个任务则不提交,如果小于3 则提交任务。” 根本不需要检测线程池中工作线程数量.
----------------------------------------------
-
作者:
2019/9/12 9:15:36
20楼:
楼上说不用检查数量,也对。用类工厂模式。问线程池要空闲线程对象,如果没有就拿不到。当然线程池本身还是要有一个上限数量的设置。这种模式的好处是,外部使用线程池的代码,无需去判断线程池现在有多少个空闲,够用不够用。这些应该是线程池自己搞定的事。外面只需要问它拿空闲对象。这样简化使用,降低耦合。 TTask 只是把某些需要用到线程的场景,代码上简化掉了。它还是个线程。和它类似的东西,很多年以前,就有第三方控件提供同样的功能了。比如 JEDI 那套。 Parallel 是个好东西,很简单地就可以整出并行而且可读性强的代码来。我实际测试过 Parallel,在可以并行处理的地方比如逐个像素处理图片,用了它,确实根据 CPU 内核数量缩短了处理时间,而且代码还简单好懂。
----------------------------------------------
-
作者:
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; 伪代码,简单,清爽。
----------------------------------------------
-
作者:
2019/10/12 20:46:21
22楼:
@zwjchinazwj 我又N个任务 不定长 有可能100 1000 1W 甚至10W任务。 我需要程序维持稳定的10线程做任务。每个任务我会传不同参数 请问用TTask 如何能方便快捷。 我用线程池获取空闲线程是 为了维持10线程工作。 不要说让我生成10W Task数组哦。。。 另外waitall我记得最大是64把。
----------------------------------------------
-
作者:
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/ 不過如果是要 萬級 的多工,如果大大有找到穩定的元件或方式,請分享,謝謝
----------------------------------------------
-
作者:
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
----------------------------------------------
-
作者:
2019/10/14 15:51:40
25楼:
@zwjchinazwj 我没有否定它 我只是说 用TTask如何使用 类似这种场景 我遍寻资料 总感觉我的用法不对 我是虚心请教
----------------------------------------------
-
作者:
2019/10/14 16:47:52
26楼:
这些都没有linux下的进程机制好,我用freepascal结合php的多进程机制用的很好
----------------------------------------------
-
作者:
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;
----------------------------------------------
-
作者:
2019/10/14 22:43:19
28楼:
@zwjchinazwj 谢谢指点。 Task能否传递类似函数指针的参数呢? 就是 TTask.Run ( //Execute every thing you want. ); 这个任务逻辑代码 可以用其他function 来分离出来。不然每次都得写。
----------------------------------------------
-
作者:
2019/10/14 22:52:04
29楼:
你自己思考尝试吧,你需要自己去学习摸索。
----------------------------------------------
-