CnPack Forum


 
Subject: 如何设置或控制线程池中线程执行的时间间隔呢?
cgs
新警察
Rank: 1



UID 41580
Digest Posts 0
Credits 6
Posts 2
点点分 6
Reading Access 10
Registered 2009-1-5
Status Offline
Post at 2009-1-5 09:34  Profile | Blog | P.M. 
如何设置或控制线程池中线程执行的时间间隔呢?

在cnpack组件包中含有线程池单元(CnThreadPool.pas)、在该组件包中也含有一个线程池使用的 demo, 该 demo 可以通过监听端口,接受线程池发送的 TCP 请求信息。发送请求信息时,是可以通过设置参数,按照一定的时间间隔发送请求,这些请求信息会被添加到队列中,由线程池中的线程执行,按照 CnThreadPool 实现单元的介绍,是可以通过设置相关参数控制线程池中的最少线程数量和最多线程数量,我现在的问题是:如何可以控制线程池中线程的执行时间间隔,比如线程池中目前保持有两个线程A、线程B,我希望能够控制这两个线程的执行时间间隔, 因为在向某些服务器请求信息时,如果请求的时间间隔太短(或在短时间内并发请求的线程过多,就会受到服务器的暂时拒接),我希望通过调节线程池中线程之间的执行时间间隔而达到与服务器和谐的目的。在 CnThreadPool 线程池实现单元中,相关参数如下:

  TCnTaskDataObject -- 线程池线程处理数据的封装
    线程池中的线程处理任务所需的数据的基类
    一般情况下,要实现某种特定的任务就需要实现相应的一个
  从该类继承的类
    Duplicate -- 是否与另一个处理数据相同,相同则不处理
    Info -- 信息,用于调试输出

  TCnPoolingThread -- 线程池中的线程
    线程池中的线程的基类,一般情况下不需要继承该类就可以
  实现大部分的操作,但在线程需要一些外部环境时可以继承该
  类的构造和析构函数,另一种方法是可以在线程池的相关事件
  中进行这些配置
    AverageWaitingTime -- 平均等待时间
    AverageProcessingTime -- 平均处理时间
    Duplicate -- 是否正在处理相同的任务
    Info -- 信息,用于调试输出
    IsDead -- 是否已死
    IsFinished -- 是否执行完成
    IsIdle -- 是否空闲
    NewAverage -- 计算平均值(特殊算法)
    StillWorking -- 表明线程仍然在运行
    Execute -- 线程执行函数,一般不需继承
    Create -- 构造函数
    Destroy -- 析构函数
    Terminate -- 结束线程

  TCnThreadPool -- 线程池
    控件的事件并没有使用同步方式封装,所以这些事件的代码
  要线程安全才可以
    HasSpareThread -- 有空闲的线程
    AverageWaitingTime -- 平均等待时间
    AverageProcessingTime -- 平均计算时间
    TaskCount -- 任务数目
    ThreadCount -- 线程数目
    CheckTaskEmpty -- 检查任务是否都已经完成
    GetRequest -- 从队列中获取任务
    DecreaseThreads -- 减少线程
    IncreaseThreads -- 增加线程
    FreeFinishedThreads -- 释放完成的线程
    KillDeadThreads -- 清除死线程
    Info -- 信息,用于调试输出
    OSIsWin9x -- 操作系统是Win9x
    AddRequest -- 增加任务
    RemoveRequest -- 从队列中删除任务
    CreateSpecial -- 创建自定义线程池线程的构造函数
    AdjustInterval -- 减少线程的时间间隔
    DeadTaskAsNew -- 将死线程的任务重新加到队列
    MinAtLeast -- 线程数不少于最小数目
    ThreadDeadTimeout -- 线程死亡超时
    ThreadsMinCount -- 最少线程数
    ThreadsMaxCount -- 最大线程数
    OnGetInfo -- 获取信息事件
    OnProcessRequest -- 处理任务事件
    OnQueueEmpty -- 队列空事件
    OnThreadInitializing -- 线程初始化事件
    OnThreadFinalizing -- 线程终止化事件
********************************************************)

请大家指点一下,为了实现我希望的那种线程控制目的,是否可以通过设置上述相关参数实现?还是需要自己对某些事件进行扩展处理呢?谢谢。
Top
shenloqi
灌水处处长
Rank: 4



UID 34
Digest Posts 1
Credits 287
Posts 179
点点分 287
Reading Access 10
Registered 2003-3-15
Status Offline
Post at 2009-1-5 10:33  Profile | P.M. 
你可以在线程池的OnProcessRequest事件中加上延时代码。如果要防止线程池中的各个线程一起去访问(题外话:目前线程池没有增加如一秒内只能启动CPU核心数目这么多个线程的选项,所以可能当任务一下子有很多的时候出现突然多了很多线程——目前要模拟实现这个能力,可以用一个计时器慢慢的设置线程池的最大线程数目),可以设置一个最后访问时间的变量(需要锁),得到这个变量的线程延后一段时间之后改写该变量,然后交出锁,这样就能防止并发过多的情况了。
Top
cgs
新警察
Rank: 1



UID 41580
Digest Posts 0
Credits 6
Posts 2
点点分 6
Reading Access 10
Registered 2009-1-5
Status Offline
Post at 2009-1-5 10:58  Profile | Blog | P.M. 
回复 #2 shenloqi 的帖子

对,我就是希望能够防止线程池中的各个线程一起去访问,希望线程池中的线程能够按照一定的时间间隔逐个去访问,  不过这样的话,又感觉没有发挥线程池的优势,与单线程请求好像没有很大的区别。
Top
shenloqi
灌水处处长
Rank: 4



UID 34
Digest Posts 1
Credits 287
Posts 179
点点分 287
Reading Access 10
Registered 2003-3-15
Status Offline
Post at 2009-1-6 10:36  Profile | P.M. 
如果只是一个个去访问,等待访问结束之后再返回结果,那么单独开一个线程也是可以的,就不需要线程池了。不过使用线程池可以做到不同时开很多并发的连接请求,但是同时有多个线程在访问服务器。
而且线程池这么做完全可以实现让不同的Task都去在线程池中执行(前提是有不同的Task类型和与之对应的Task处理方法),当要做到这些功能时采用单独的线程可能就会复杂很多了。
Top
shenloqi
灌水处处长
Rank: 4



UID 34
Digest Posts 1
Credits 287
Posts 179
点点分 287
Reading Access 10
Registered 2003-3-15
Status Offline
Post at 2009-1-6 10:44  Profile | P.M. 
对了,如果有谁愿意的话,建议为这个线程加上Delphi2009的一些功能,使其提供更友好的API,比如,利用泛型实现Task的通用子类,使用匿名函数来对实例化的Task进行操作,这样用户在一般情况下就不需要对这个线程池有任何了解,但是任务都会通过线程池来实现了。
Top
 




All times are GMT++8, the time now is 2024-11-25 12:18

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.0.0  © 2001-2006 Comsenz Inc.
Processed in 0.010098 second(s), 8 queries , Gzip enabled

Clear Cookies - Contact Us - CnPack Website - Archiver - WAP