linux的轮询机制

用户空间与内核空间

操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。
为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操心系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。
针对linux系统,比如32位OS,那么虚拟空间(虚拟存储空间)为4GB。linux将最高的1G字节(0xC0000000~0xFFFFFFFF)作为内核空间;将较低的3G字节(0x00000000~0xBFFFFFFF)作为用户空间。

进程/线程切换

为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这些都是与内核密切相关的。

进程/线程却换又可以称为任务切换,或上下文切换。

一次切换需要经历如下的步骤:

  1. 保存处理机上下文,包括程序计数器和其他寄存器。
  2. 更新PCB信息。
    1. PCB:进程控制块。属于进程实体的一部分,记录了OS所需要的用于描述进程情况以及控制进程运行所需要的全部信息。
    2. PCB的作用就是使得不能独立运行的程序,成为一个能独立运行的基本单位。OS就是根据PCB来对并发执行的进程进行控制和管理的。
    3. 主要包含如下信息:进程标识符(外部标识符、内部标识符)、处理机状态信息、进程调度信息、进程控制信息。
    4. 组织方式:链接方式 和 索引方式。
  3. 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列中。
  4. 选择另一个进程执行,更新它的PCB。
  5. 更新内存管理的数据结构。
  6. 回复处理机上下文。

进程阻塞

正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使自己由运行状态变为阻塞状态。可见,进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞状态。当进程进入阻塞状态,是不占用CPU资源的。

文件描述符

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。

缓存 I/O

缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。

缓存 I/O 的缺点:
数据在传输过程中需要在应用程序地址空间和内核进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。

select轮询机制

select本质上是通过检查存放在fd标志位来判断是否可以进行下一步的操作。

具体过程是:通过select()系统调用来监视文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。

缺陷:

  • 单个进程可监视的fd数量被限制(1024)
  • 需要维护一个用来存放大量fd的数据结构,使得用户空间和内核空间在传递该结构时复制开销大

poll

本质上和select一样,只是它采用了链表的数据结构,没有最大文件描述符数量的限制。

select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息,这种方式称为水平触发(Level Triggered)

epoll

results matching ""

    No results matching ""