QNX 基础认知

文章目录

    • QNX微内核介绍
      • Threads run code, Processes own resources
        • 1. 进程PID
          • 进程API
        • 2. 线程TID
          • 线程API
        • 3. Synchronization
      • Kernel
        • Kernel 提供的进程间的通信方式
      • Process Manager
      • Scheduling 调度
      • Resource Manager
    • IPC 进程间通信

QNX微内核介绍

QNX采用微内核结构,也就是说,内核非常非常非常小。这样一方面启动速度非常快,另一方面安全性稳定性大大提高。
QNX构架是有一个微型内核,然后又包含许多相关进程。这样的好处是,即使有一个进程出错,也不会影响内核。
各个服务进程以及应用进程之间通过内部进程通信IPC的方式进行沟通,如下图:
QNX 基础认知_第1张图片

Threads run code, Processes own resources

1. 进程PID

进程包含自己的一些资源,比如说ID, 内存(代码和数据),计时器,等等…, 并且这些资源是被保护的,也就是说其他进程不能访问
QNX 基础认知_第2张图片

进程API

fork(), exec(), spawn(), spawn(), posix_spawn()**
QNX 基础认知_第3张图片
fork意为分叉, 它的作用是复制当前进程(包括进程内存里的堆栈数据),变成两个进程同时执行下去,实际引用中单纯让程序分叉意义不大,我们fork一个子程序,是为了让子进程单独执行一段代码,实现与主进程不同的功能.
fork() 实际上有返回值, 主进程里fork()函数返回主进程的pid, 而子进程里返回0.

2. 线程TID

一个线程就是一个执行流或者控制流。
它也有一些属性,比如: 优先级, 调度算法,寄存器集合,CPU掩码(用于多核应用),…
QNX 基础认知_第4张图片
一个Process里的Threads都有属于自己的内存地址(虚拟地址), 其他资源都是共享的
QNX 基础认知_第5张图片
每一个thread都有一个最大体积,也不是每一个都需要分配物理内存
QNX 基础认知_第6张图片

线程API

pthread_create() 创建线程, 返回tid,
pthread_attr_init() 设置线程的default值

如果想设置thread优先级和调度算法:

param.sched_priority = 15; %优先级值为15
pthread_attr_setschedparam (&attr, &param); %给该thread设定优先级
pthread_attr_setschedpolicy (&attr, SCHED_RR); %设定调度算法为Round-Robin

Process里面,第一个thread就是main thread, 因为它调用了整个process的main()函数. 如果exit()被调用,那么整个process就结束死亡了,所有的相应的资源(内存,channels等)都会被释放或清理
同样的道理,如果在一个thread里, 如果pthread_exit()被调用了,那么thread也就会结束死亡。

3. Synchronization

multi-threads引入了新的问题,比如公用内存空间,多个线程同时写入会相互覆盖对方的值,读取时页不知道什么时候时稳定的有效数据.
所以我们需要同步机制 Synchronization来协调管理

3.1 **Mutual exclusion (Mutex) **
Mutual exclusion (缩写Mutex)意味着只有一个thread在某一时间里可以执行某段重要的代码段,或者读写一些特别的数据
一个形象的比喻:
把厕所空间比喻成内存空间,每次只能进去一个人,里面有人的时候,其他人就不能进去了。这代表一个thread使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存. 问题是如何防止别人也同时进去呢?
QNX 基础认知_第7张图片
一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。
Mutex就是一个process内的对于所有threads来说的全局0/1变量,你要锁的时候就把这个全局变量Mutex设置为1,其他的thread读到这个Mutex的时候就知道你在使用,就停下来等,知道你用完了把Mutex设置回0,然后别的进程才可以进去用
当然一旦锁定了Mutex,该thread的优先级就会上升。因为系统当然希望这个thread赶紧运行完毕,毕竟不能占着茅坑不拉屎。
QNX 基础认知_第8张图片
3.2 条件锁 Condvars
光有互斥锁还是不够,最好有一把聪明的互斥锁。比如说,只有满足了某种条件(收到某种信号)的情况下,才能解锁。这样就会更高效的执行程序功能

Kernel

核心模块,因为他,系统的各个模块可以协作. 其他程序可以通过kernel call的方式来调用kernel模块,
QNX 基础认知_第9张图片
Kernel call 采用抢占方式(pre-emptable) 被调用, 好处是,响应新的事件速度会很快,但是要花更多的事件去回复原来被打断的kernel call.
内核可以提供不同的服务, 比如: 同步, 时钟, 进程间通信,调度 …
QNX 基础认知_第10张图片

Kernel 提供的进程间的通信方式

  • Messages 进程间交换信息
  • Pluses 传递通知给进程
  • Signals 终端进程,让它做别的事情

QNX 基础认知_第11张图片
QNX 基础认知_第12张图片
QNX 基础认知_第13张图片
事实上,kernel可以被想象成一个library, 并没有一直不停运行的循环进程. 只有在被调用的时候才运行

Process Manager

procnto = Process manager + Micarokernel
QNX 基础认知_第14张图片
Process Manager提供服务包括:

  • 捆绑一组threads一起进入process
  • 内存保护,内存空间管理, QNX使用虚拟内存地址
  • 路径名管理
  • Process创建和结束
    QNX 基础认知_第15张图片

Scheduling 调度

Thread有两个状态: blocked 和 runnable
Thread有优先级: 0-255, kernel总是选择优先级最高的thrad来执行
Thread有属于自己的调度算法: Round-robin(轮询), FIFO …

Round-robin 该术语来源于含义为“带子”的法语词ruban,久而被讹用并成为惯用语。在17、18世纪时法国农民希望以请愿的方式抗议国王时,通常君主的反应是将请愿书中最前面的两至三人逮捕并处决,所以很自然地没有人希望自己的名字被列在前面。为了对付这种专制的报复,人们在请愿书底部把名字签成一个圈(如同一条环状的带子),这样就找不出打头的人,于是只能对所有参与者进行同样的惩罚。

Resource Manager

资源管理器,提供POSIX规范的接口来管理资源. 比如open文件,read文件,write文件…

IPC 进程间通信

下一章: IPC 进程间通信

参考

你可能感兴趣的:(QNX,Linux,C/C++)