当前位置:  开发笔记 > 编程语言 > 正文

用于执行具有不同优先级的任意任务的线程池

如何解决《用于执行具有不同优先级的任意任务的线程池》经验,为你挑选了1个好方法。

我正在尝试为我的工作设计一个具有很多设计要求的线程池.这对于工作软件来说是一个真正的问题,这是一项艰巨的任务.我有一个有效的实现,但我想把它扔到SO,看看人们可以提出什么有趣的想法,以便我可以比较我的实现,看看它是如何叠加的.我试图尽可能地满足要求.

线程池需要执行一系列任务.任务可以是短时间运行(<1秒)或长时间运行(数小时或数天).每个任务都有一个相关的优先级(从1 =非常低到5 =非常高).任务可以在其他任务运行时随时到达,因此当它们到达时,线程池需要选择这些并在线程可用时安排它们.

任务优先级完全独立于任务长度.实际上,如果不运行任务就无法确定任务可以运行多长时间.

某些任务受CPU限制,而有些任务受IO限制.事先不可能知道给定的任务是什么(虽然我猜在任务运行时可能会检测到).

线程池的主要目标是最大化吞吐量.线程池应该有效地使用计算机的资源.理想情况下,对于CPU绑定任务,活动线程的数量将等于CPU的数量.对于IO绑定任务,应分配比CPU更多的线程,以便阻塞不会过度影响吞吐量.最大限度地减少锁的使用和使用线程安全/快速容器非常重要.

通常,您应该以更高的CPU优先级运行更高优先级的任务(参考:SetThreadPriority).较低优先级的任务不应"阻止"更高优先级的任务运行,因此如果在所有低优先级任务运行时出现更高优先级的任务,则优先级较高的任务将运行.

任务具有与其关联的"最大运行任务"参数.每种类型的任务只允许一次最多运行该任务的许多并发实例.例如,我们可能在队列中有以下任务:

A - 1000个实例 - 低优先级 - 最大任务1

B - 1000个实例 - 低优先级 - 最大任务1

C - 1000个实例 - 低优先级 - 最大任务1

工作实现只能同时运行(最多)1 A,1 B和1 C.

它需要在Windows XP,Server 2003,Vista和Server 2008(最新的服务包)上运行.


作为参考,我们可能会使用以下界面:

namespace ThreadPool
{
    class Task
    {
    public:
        Task();     
        void run();
    };

    class ThreadPool
    {    
    public:
        ThreadPool();
        ~ThreadPool();

        void run(Task *inst);
        void stop();
    };
}

DrPizza.. 5

那么我们将选择什么作为这个的基本构建块.Windows有两个看起来很有前途的构建块: - I/O完成端口(IOCP)和异步过程调用(APC).这两个都为我们提供了FIFO排队,而不必执行显式锁定,并且在调度程序等位置具有一定量的内置OS支持(例如,IOCP可以避免某些上下文切换).

APC可能稍微适合一些,但我们必须对它们略微小心,因为它们不是很"透明".如果工作项执行可警告的等待(:: SleepEx,:: WaitForXxxObjectEx等)并且我们意外地将APC分派给线程,则新分派的APC将接管该线程,暂停先前执行的APC,直到新的APC为止.完了.这对我们的并发要求不利,并且可能使堆栈溢出更有可能.



1> DrPizza..:

那么我们将选择什么作为这个的基本构建块.Windows有两个看起来很有前途的构建块: - I/O完成端口(IOCP)和异步过程调用(APC).这两个都为我们提供了FIFO排队,而不必执行显式锁定,并且在调度程序等位置具有一定量的内置OS支持(例如,IOCP可以避免某些上下文切换).

APC可能稍微适合一些,但我们必须对它们略微小心,因为它们不是很"透明".如果工作项执行可警告的等待(:: SleepEx,:: WaitForXxxObjectEx等)并且我们意外地将APC分派给线程,则新分派的APC将接管该线程,暂停先前执行的APC,直到新的APC为止.完了.这对我们的并发要求不利,并且可能使堆栈溢出更有可能.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有