线程由线程句柄(或 ID)、当前指令指针(PC)、CPU 寄存器集合和线程栈组成。每一个线程都是操作系统调度的单位。线程本身只拥有有限的、在运行中必不可少的资源,例如 CPU 寄存器与栈等。内核线程共享内核所有资源,例如内核文件描述符表,而进程内线程则共享使用进程内所有资源,例如进程文件描述符表。一个 CPU 在一个时刻只能运行一个线程(多 CPU 系统可同时运行多个线程),如果系统中存在多个线程,则 CPU 需要在几个线程之间切换运行,从宏观上来看相当于多个线程并发执行。CPU 什么时刻运行哪一个线程是由操作系统调度算法决定的,例如分时操作系统将时间分成若干个小的片段称之为时间片,每个线程运行一段时间后操作系统将会命令CPU 切换到另一个线程执行。实时操作系统则不然,实时操作系统中每一个线程都拥有自己的优先级,当优先级高的线程需要执行时,操作系统会立即切换当前 CPU 去执行更高优先级的线程,这样的调度算法满足系统对实时信号响应的需要。
线程状态机
同一进程或内核中的多个线程之间可以并发执行。但由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有阻塞、就绪和运行三种基本状态。这三种状态的含义如
下:
阻塞:线程缺少使其运行的条件或资源,必须等条件满足后方可进入就绪态;
就绪:线程已经拥有使其运行的一切资源,等待操作系统调度;
运行:线程已被操作系统调度(操作系统将一个 CPU 分配给线程用于执行线程代码)。
SylixOS 系统中被创建出来的线程总是处于这三种状态中的任意一种,其中阻塞态又因
阻塞原因不同分为:等待信号量、等待消息、睡眠等。线程之间的状态切换如图所示。SylixOS先实现自己的线程API函数,再兼容POSIX接口。
SylixOS 线程调度
实时系统和分时系统的一个显著差异体现在调度策略上。实时系统调度关心的是对实时事件的响应延时,而传统的分时系统调度时要考虑的目标是多方面的:公平、效率、利用率、吞吐量等。因此实时系统通常采用优先级调度,即操作系统总是从就绪任务队列中选择最高优先级运行。
优先级调度
调度其他线程,这种调度方式称为“不可抢占式调度”,也就是说线程主动让出处理器后系统才重新根据优先级调度选择线程。这种调度方式会造成就绪的高优先级线程不能及时地得到响应,因此也就降低了实时响应速度。当一个线程正在运行时,操作系统可以根据某种原则剥夺已分配给它的处理器转而分配给其他线程,这种调度方式称为“可抢占式调度”,这种调度器原则有:优先级原则、时间片原则等。SylixOS 中不同优先级之间采用可抢占式的优先级调度原则。根据上述可以看出,当注重实时响应时,应该采用“可抢占式调度”方式,只要有更高优先级线程就绪,系统立即中断当前线程来调度高优先级的线程,以确保任意时刻高优先级的线程都能得到处理器,这是实时系统的基本要求。SylixOS 内核支持 256 个优先级0~255。优先级 0 为最高优先级,优先级 255 为最低优先级。在线程创建时确定优先级,并允许程序运行中动态修改。但是对于内核而言,从就绪队列中选择一个线程调度时优先级是确定的,也就是说内核不会动态计算每个线程的优先级,因此这种调度策略属于静态调度策略。相对于动态调度策略调度时需要根据某个目标动态确定线程优先级并调度。静态调度策略效率高于动态调度策略。
RR(Round-Robin)调度
没有因阻塞等原因让出处理器,线程将一直运行下去,在此情况下,同优先级线程将得不到运行。RR 调度基于这样的哲学:在更高优先级线程调度依然优先运行的前提下,同优先级线程之间调度时追求一定意义上的公平。RR 调度将线程运行划分为时间片,当线程运行一个时间片后,内核将其调出处理器并放在同优先级就绪线程队列尾部,然后重新选择下一个符合条件的线程运行。RR 调度的效果是将每个线程运行一个时间片后“让出”处理器给下一个线程,如轮转一样,所以也称轮转调度。可见,RR 调度并没有改变“基于优先级”和“可抢占”这两个实时调度的特征。如果采用 RR 调度策略,一个值得考虑的问题是时间片大小的确定,如果时间片小有利于同优先级线程公平共享处理器,但是增加了调度开销,如果增大时间片调度开销降低,但调度效果将趋向于优先级调度。合理的时间片将是在公平和效率之间的折衷。
SylixOS RMS 调度
为周期性任务解决多任务调度冲突的一种非常好的方法是速率单调调度(RateMonotonic Scheduling RMS),RMS 基于任务的周期指定优先级。在 RMS 中,最短周期的任务具有最高优先级,次短周期的任务具有次高优先级,依次类推。当同时有多个任务可以被执行时,最短周期的任务被优先执行。如果将任务的优先级视为速率的函数,那么这就是一个单调递增函数。