"); //-->
针对QNX的核心和服务主要分一下几点介绍
简介
系统服务
线程和进程
线程调度
同步服务
时钟服务
中断服务
一、简介
所有的系统宏观上都差不多,QNX的OS是基于下图的基础上创建的:
QNX核心[procnto]主要使用c语言实现,性能的提升与核心大小的提炼都是通过算法和数据接口的重新设计来实现的,而不是使用汇编来实现。
二、系统服务
procnto中是包含的一下一下几种服务(进程与线程,同步服务,时钟服务,中断服务),估计为几种机能[threads、message passing、signals(信号量)、clocks、timers、interrupt handlers、semaphores、mutual exclusion locaks(mutexes)、condition variables(condvars)、varriers],其他的机能[io等]都是通过可选进程与共享库提供的。
三、线程和进程
线程是最小的执行单元,而进程一个一堆线程的集合。由于每个进程都有自己的地址空间,所以多个进程的分割能够提升系统的可靠性和可维护性,降低系统的耦合度,更容易进行模块化设定,但也导致了进程切换时的资源消耗。可以使用多线程提升同一进程内的执行效率。
1、线程的属性
虽然线程共享了进程的地址空间,但是它也有自己的私有数据,由于线程的属性还是比较多,主要的属性有:tid:ID号和Priority:优先级
这一块好型用到了稀疏矩阵的算法
2、线程的生命周期
线程的生命周期如下图所示:
四、线程调度
1、什么时候做出调度决定
当线程的状态改变时确定线程的调度决定。当前线程处于以下状态时,调度器会切换执行环境。
・is blocked[阻塞]:当执行线程必须等待某一事件发生(如IPC请求的响应,Mutex的阻塞等)时,线程会被阻塞。优先级最高的可执行(READY)线程开始执行,被阻塞的线程在阻塞解除后会被置于对应优先级的可执行队列的末尾。
・is preempted[抢占]:当更高优先级的线程被置于可执行队列时,当前线程会被抢占。被抢占现存有被置于对应优先级的可执行队列的开头。
・yielded[放弃]:当前执行线程主动放弃处理器资源时,会被置于对应优先级的可执行队列的末尾。优先级最高的可执行(READY)线程开始执行。
2、调度优先级
QNX Neutrino支持256个优先级,0对应idle线程,其中1~63可被用于非root线程,63以上被用于root线程。可以使用[procnto -P 设定值]去修改这个临界值。子线程会继承父线程的优先级。多数情况下可用线程按照FIFO方式排列在各自的优先级队列中。例外:当服务线程从RECEIVE-阻塞中恢复时,会被置于对应优先届队列的开头。
3、调度策略
请参考上一篇:浅谈QNX的调度算法
五、同步服务
1、mutexes:mutual exclusion locks[互斥体]
mutexes[互斥体]是最简单的同步服务,通常被用来保证多个线程对共享数据的独占访问。同时只能由一个线程能够拥有mutexes的锁。当一个线程试图对一个已经被锁的mutexes取锁时,这个县城将被阻塞。当解锁时,最好权限的被阻塞线程被恢复,并取得mutexes的锁。
当一个拥有更高优先级的线程试图dui一个被锁metuxes取锁时,当前的线程的权限会被调整为同样的优先级,当该进程解锁时恢复自己本来的优先级。
2、Condvars:condition variables[条件变量]
condvars[条件变量]通常用于在特定条件的满足之前,阻塞一个线程。总是和mutex一起使用。Condvars在等待时会释放对应的Mutex。唤醒的线程重新获取Mutex并从 阻塞状态返回之前,条件可能会发生变化,所以条件的判断通常会放到一个循环中
3、Barriers[栅栏]
Barriers能够实现在多线程环境中,在被阻塞县城达到指定数量之前阻塞所有线程。在初始化Barriers时需要指定阻塞线程的数量,当调用wait方法的线程没有达到这个数量之前这些线程都会被阻塞。当阻塞的现存达到这个数量时,所以被阻塞线程会被同时解除阻塞。
4、Sleepon locks[睡眠锁]
Sleepon locks[睡眠锁]和Condvars[条件变量]非常相似,他们都是用来在满足指定条件之前阻塞线程。但不同的是Condars需要针对每个判断分配单独的Condvars,而Sleepon locks使用同一个Mutex并且动态自动分配Condvars。
5、Reader/writer locks[读写锁]
Reader/writer locks[读写锁]通常表达为可以有多个消费者但是只能有一个生产者锁[Multiple readers,single writer locks]。通常被用于多个线程读写一组数据时。它容许多个线程同时读取数据,但是同时只能有一个线程写数据。当一个线程试图取得一个写锁时,他会阻塞这个线程直到所有当前的读锁释放为止。当有多个写线程和读线程阻塞的,系统会优先执行写线程,当所有写锁释放后再执行读线程。Mutex只容许单线程操作,而Reader/writer locks容许多个读线程同时操作。6、Semaphores[信号变量]
Semaphores[信号变量]能够控制通过(post)或阻塞(wait)线程。Post操作会增加Semaphore,Wait操作会减少它。当Semaphore为正时,一个wait操作不会被阻塞。当Semaphore不为正时,Wait操作会阻塞直到其他现存调用了Post操作。Semaphore能够实现一个单独的唤醒线程。Semaphore能过实现多进程间的同步,而Mutex只能在一个进程内同步。在进程内Mutex比Semaphore快。
7、Synchronization via scheduling algorithm[通过调度算法实现同步]
POSIX FIFO(First in First Out)规定在NON—SMP环境下,不会在让相同优先级的线程同步运行。FIFO调度算法规定在相同优先级的线程被调度时,执行当前线程直到其释放处理器资源为止。释放处理器资源包括当前线程应要求其他进程的服务而阻塞和Signal发生时。
8、Synchronization via message passing[通过消息传递实现同步]
Send/Receive/Reply message-passing IPC services能够实现内涵的同步。
可以参考前面写的IPC进程通信这一章。
9、Synchronization via atomic operations[通过原子操作实现同步]
QNX Neutrino在<atomic.h>中提供一下原子操作
・adding a value
・subtracting a value
・clearing bits
・setting bits
・toggling(complementing) bits
同步的实现可以有下面的函数调用:
六、时钟服务
Clock服务用来维护系统的时间。提供了各种设定和取得系统时间的接口。
QNX有全功能的timer[计时器],它提供三个计时方式①一个绝对时间②一个相对时间③指定周期。
七、中断处理
无论如何实现设备在接受外部事件到开始之间总是会有一定的时间间隔,叫做Latency[延迟]。一下两种必需考虑:
中断延迟:是指设备中断发生后到设备中断处理程序开始响应之间的时间间隔。如下图所示:
调度延迟:当一个底层硬件中断处理程序需要调度一个高层线程的时候,通常需要分发一个时间,这是产生Scheduling letancy。Seheduling latency是指设备中断处理程序结束后到设备驱动开始响应之间的时间间隔。如下图所示:
QNX Neutrino完全支持Nested interrupts[嵌套中断]。优先级高的中断可以抢占优先级低的中断。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。