Windows
CNC多任务调度策略
一般对于单CPU 的CNC系统,系统软件结构采用前后台式。前台程序承担几乎全部实时功能,后台程序用来完成准备工作和管理工作,任务的调度机制采用优先抢占调度与时间片轮转相结合的机制。
(1)优先抢占调度机制
为了满足CNC 实时任务的要求,系统的调度机制必须具有能根据外界的实时信息以足够快的速度(在系统规定的时间内)进行任务调度的能力。优先抢占调度机制就是能满足上述要求的调度技术,它是一种基于实时中断技术的任务调度机制。
优先抢占调度机制,其功能有两个:
1优先调度。在CPU 空闲时,当同时有多个任务请求执行时,优先级高的任务将优先得以满足。
劳动节主题
2抢占方式。在亭台轩榭CPU 正在执行某任务时,若另一优先级更高的任务请求执行,CPU 将立即终止正在执行的任务,转而响应优先级高的任务的请求。
优先抢占调度机制是由硬件和软件共同实现的,硬件主要提供支持中断功能的芯片和电路,如中断管理芯片(8259或功能相同的芯片),定时器计数器(8263、8294 等)。软件主要完成对硬件的初始化,任务优先级的定义方式、任务切换处理(断点的保护与恢复、中断向量的保存与恢复等)。
(2)时间片轮转调度机制
任务就绪队列往往按任务到达的时间来排序。任务调度程序总是选择就绪队列中的第一个任务,也就是说按照先来先服务的原则调度,即根据任务进入就绪队列的先后次序来占有CPU,一旦一任务占有CPU,它就一直运行下去,直到该任务完成其工作或因等待某事件而不能继续运行时才释放CPU,但一旦任务占有CPU 仅使用一个时间片。在使用完一个时间片后,任务还没有完成其运行,它也必须释放出(被抢占)CPU 给下一个就绪的任务。而被抢占的任务返回到就绪队列的末尾重新排队等候再次运行。
时间片的大小对系统运行的影响很大。如果时间片很大,大到一个任务足以完成其全部运行工作所需的时间,那么时间片轮转策略将退化为先来先服务策略了。如果时间片很小,那么长跑加油稿CPU 在任务间的转接工作过于频繁,CPU 真正用于运行任务的时间将会减小。
(3)调度策略
1、确定任务优先级,突发性实时任务具有最高优先级。美人与大排档
2、为其它各任务分配执行周期。如位控为4ms,插补为8ms,预处理为16ms,背景程序为55ms。即在55ms时间片内,最先执行位控任务,位控任务完成后,接着执行插补任务,如果4ms时间到,则插补将被终止,又开始执行位控,当位控执行完后,从刚才中断处接着执行插补,插补执行完后接着执行预处理,以此类推。
3、在背景程序中,各任务分配相同的优先权,当一个任务执行完后,就绪队列中最前头的任务占据CPU感慨的近义词运行,而先前运行任务失去对CPU的控制退至队列尾,直到循环使其达到队头时才重新获得控制权,即按先来先服务的原则调度。
一拍网4、当突发性实时任务发生,如故障中断、机床PLC中断及其它异常发生时,当前正在运行
的任务将立刻终止执行,系统保存现场环境后,立刻去响应突发性实时中断信号,在执行完突发性实时任务后,回到刚才被强行终止的任务处继续执行该任务。
5、在Windows 下采用多线程来实现多任务控制。
在数控软件中,建立主控线程(监控和界面线程)和加工运行线程。主控线程主要运行背景程序,通过Windows 消息驱动实现其操作流程。加工运行线程由主控线程启动和消除。
6、为协调各线程、各任务之间的运行,在软件中建立多个数据缓冲区,具体的实现方法是:
a为多缓冲区分配内存,建立指向当前缓冲区的读、写指针,构成一个环形多缓冲区;
b为每块内存设置一个标志位,作为对各缓冲区进行操作的判断依据;
c每读一个缓冲区,对该缓冲区设置已读标志,当前读指针向前移动一个缓冲区;
d 每写一个缓冲区,对该缓冲区设置已写标志,当前写指针向前移动一个缓冲区;
e对于当前操作未结束的缓冲区,设置正在操作标志,禁止其它操作。
采用这种方法,将系统中必须在单个插补周期内完成的运算“均化”在多个插补周期内完成,有效的利用了CPU的计算时间,提高了系统的工作效率。
结论
开发Windows 下的CNC系统是数控技术发展的必然趋势,利用Windows 的多线程和硬中断的机制,采用优先抢占调度和时间片轮转调度相结合的策略,可实现Windows 下的CNC实时多任务的控制要求。
Linux
进程调度策略
调度程序运行时,要在所有处于可运行状态的进程之中选择最值得运行的进程投入运行。选择进程的依据是什么呢?在每个进程的task_struct 结构中有这么四项:
policy, priority , counter, rt_priority
这四项就是调度程序选择进程的依据.其中,policy是进程的调度策略,用来区分两种进程-
微波炉加热
实时和普通;priority是进程(实时和普通)的优先级;counter 是进程剩余的时间片,它的大小完全由priority决定;rt_priority是实时优先级,这是实时进程所特有的,用于实时进程间的选择。
首先,Linux 根据policy从整体上区分实时进程和普通进程,因为实时进程和普通进程度调度是不同的,它们两者之间,实时进程应该先于普通进程而运行,然后,对于同一类型的不同进程,采用不同的标准来选择进程:
对于普通进程,Linux采用动态优先调度,选择进程的依据就是进程counter的大小。进程创建时,优先级priority被赋一个初值,一般为0~70之间的数字,这个数字同时也是计数器counter的初值,就是说进程创建时两者是相等的。字面上看,priority是“优先级”、counter是“计数器”的意思,然而实际上,它们表达的是同一个意思-进程的“时间片”。Priority代表分配给该进程的时间片,counter表示该进程剩余的时间片。在进程运行过程中,counter不断减少,而priority保持不变,以便在counter变为0的时候(该进程用完了所分配的时间片)对counter重新赋值。当一个普通进程的时间片用完以后,并不马上用priority对counter进行赋值,只有所有处于可运行状态的普通进程的时间片(p->;;counter
==0)都用完了以后,才用priority对counter重新赋值,这个普通进程才有了再次被调度的机会。这说明,普通进程运行过程中,counter的减小给了其它进程得以运行的机会,直至counter减为0时才完全放弃对CPU的使用,这就相对于优先级在动态变化,所以称之为动态优先调度。至于时间片这个概念,和其他不同操作系统一样的,Linux的时间单位也是“时钟滴答”,只是不同操作系统对一个时钟滴答的定义不同而已(Linux为10ms)。进程的时间片就是指多少个时钟滴答,比如,若priority为20,则分配给该进程的时间片就为20个时钟滴答,也就是20*10ms=200ms。Linux中某个进程的调度策略(policy)、优先级(priority)等可以作为参数由用户自己决定,具有相当的灵活性。内核创建新进程时分配给进程的时间片缺省为200ms(更准确的,应为210ms),用户可以通过系统调用改变它。
对于实时进程,Linux采用了两种调度策略,即FIFO(先来先服务调度)和RR(时间片轮转调度)。因为实时进程具有一定程度的紧迫性,所以衡量一个实时进程是否应该运行,Linux采用了一个比较固定的标准。实时进程的counter只是用来表示该进程的剩余时间片,并不作为衡量它是否值得运行的标准。实时进程的counter只是用来表示该进程的剩余时间片,并不作为衡量它是否值得运行的标准,这和普通进程是有区别的。上面已经看到,每个进程有两个优先级,实时优先级就是用来衡量实时进程是否值得运行的。
这一切看来比较麻烦,但实际上Linux中的实现相当简单。Linux用函数goodness()来衡量一个处于可运行状态的进程值得运行的程度。该函数综合了上面提到的各个方面,给每个处于可运行状态的进程赋予一个权值(weight),调度程序以这个权值作为选择进程的唯一依据。
Linux根据policy的值将进程总体上分为实时进程和普通进程,提供了三种调度算法:一种传统的Unix调度程序和两个由POSIX.1b(原名为POSIX.4)操作系统标准所规定的“实时”调度程序。但这种实时只是软实时,不满足诸如中断等待时间等硬实时要求,只是保证了当实时进程需要时一定只把CPU分配给实时进程。
非实时进程有两种优先级,一种是静态优先级,另一种是动态优先级。实时进程又增加了第三种优先级,实时优先级。优先级是一些简单的整数,为了决定应该允许哪一个进程使用CPU的资源,用优先级代表相对权值-优先级越高,它得到CPU时间的机会也就越大。
1 静态优先级(priority)-不随时间而改变,只能由用户进行修改。它指明了在被迫和其他进程竞争CPU之前,该进程所应该被允许的时间片的最大值(但很可能的,在该时间片耗尽之前,进程就被迫交出了CPU)。
2 动态优先级(counter)-只要进程拥有CPU,它就随着时间不断减小;当它小于0时,标记进程重新调度。它指明了在这个时间片中所剩余的时间量。
3 实时优先级(rt_priority)-指明这个进程自动把CPU交给哪一个其他进程;较高权值的进程总是优先于较低权值的进程。如果一个进程不是实时进程,其优先级就是0,所以实时进程总是优先于非实时进程的(但实际上,实时进程也会主动放弃CPU)。
当policy分别为以下值时:
1) SCHED_OTHER:这是普通的用户进程,进程的缺省类型,采用动态优先调度策略,选择进程的依据主要是根据进程goodness值的大小。这种进程在运行时,可以被高goodness值的进程抢先。
2) SCHED_FIFO:这是一种实时进程,遵守POSIX1.b标准的FIFO(先入先出)调度规则。它会一直运行,直到有一个进程因I/O阻塞,或者主动释放CPU,或者是CPU被另一个具有更高rt_priority的实时进程抢先。在Linux实现中,SCHED_FIFO进程仍然拥有时间片-只有当时间片用完时它们才被迫释放CPU。因此,如同POSIX1.b一样,这样的进程就象没有时
学习伴成长间片(不是采用分时)一样运行。Linux中进程仍然保持对其时间片的记录(不修改counter)主要是为了实现的方便,同时避免在调度代码的关键路径上出现条件判断语句 if (!(current->;;policy&;;SCHED_FIFO)){...}-要知道,其他大量非FIFO进程都需要记录时间片,这种多余的检测只会浪费CPU资源。(一种优化措施,不该将执行时间占10%的代码的运行时间减少到50%;而是将执行时间占90%的代码的运行时间减少到95%。0.9+0.1*0.5=0.95>;;0.1+0.9*0.9=0.91)
3) SCHED_RR:这也是一种实时进程,遵守POSIX1.b标准的RR(循环round-robin)调度规则。除了时间片有些不同外,这种策略与SCHED_FIFO类似。当SCHED_RR进程的时间片用完后,就被放到SCHED_FIFO和SCHED_RR队列的末尾。