Linux遵从冯诺依曼体系结构。
包含了运算器、存储器、控制器、输入设备、输出设备五大部分。
冯诺依曼体系结构以处理器为中心,输入输出设备通过运算器与存储器传送数据。
指令和数据以同等地位存储在存储器中,并可按地址寻址。
指令和数据以二进制代码表示。
指令由操作码和地址码组成。操作码表示操作的性质,地址码用来表示操作数载存储器中的位置。
指令在存储器内按顺序存放。通常情况下,指令是按顺序执行的。
实际上记录的是《Unix/Linux》编程实践教程中的Unix文件系统内部结构
要理解两个模型,一个是目录树模型,一个是文件存储模型。
理解存储设备抽象成文件系统。
在UNIX/Linux中,目录是一种特殊的文件,它是由文件和目录的序列组成,一定有"." 和 ".." 来指向本目录和父目录。根目录"/"的“..”指向自己本身。各级目录组成了树状的结构。
文件存储模型
磁盘被抽象成分区,扇区是磁盘上的基本存储单元,给磁盘块(扇区?)编号,成为文件系统的序列块。磁盘块组成的空间又可以分成3部分(每个空间都由多个磁盘块组成):超级块,i-节点块,数据区。
通俗地讲程序是一个包含可以执行代码的静态的文件。进程是一个开始执行但是还没有结束的程序的实例。
当程序被系统调用到内存以后,系统会给程序分配一定的资源(内存,设备等等)然后进行一系列的复杂操作,使程序变成进程以供系统调用。
进程的分类
按照进程的功能和运行的程序分类,进程可划分为两大类:
系统进程
可以执行内存资源分配和进程切换等管理工作,而且该进程的运行不受用户的干预,即使是root用户也不能干预系统进程的运行。
用户进程
通过执行用户程序、应用程序或内核之外的系统程序而产生的进程,此类进程可以在用户的控制下运行或关闭。
针对用户进程,又可以分为如下3类:
交互进程:由一个Shell终端其他的进程,在执行过程中,需要与用户进行交互操作,可以运行于前台,也可以运行于后台。
批处理进程:该进程是一个进程集合,负责按顺序启动其他的进程。
守护进程:守护进程是一直运行的一种进程,经常在Linux系统时启动,在系统关闭时终止。它们独立于控制终端且周期性地质学某种任务或等待处理某些发生的时间。例,httpd进程,crond进程等。
Linux 下的状态转换图
用户空间与内核空间
现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操心系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核,保证内核的安全,操心系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。空间分配如下图所示:
有了用户空间和内核空间,整个linux内部结构可以分为三部分,从最底层到最上层依次是:硬件-->内核空间-->用户空间。如下图所示:
(1) 内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码和数据。不管是内核空间还是用户空间,它们都处于虚拟空间中。
(2) Linux使用两级保护机制:0级供内核使用,3级供用户程序使用。
select函数接口
select使用实例
select缺点
select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:
1.单个进程所打开的FD是有限制的,通过 FD_SETSIZE 设置,默认1024 ;
2.每次调用 select,都需要把 fd 集合从用户态拷贝到内核态,这个开销在 fd 很多时会很大;
3.对 socket 扫描时是线性扫描,采用轮询的方法,效率较低(高并发)
poll
poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,但是它没有最大连接数的限制,原因是它是基于链表来存储的.
poll缺点
它没有最大连接数的限制,原因是它是基于链表来存储的,但是同样有缺点:
每次调用 poll ,都需要把 fd 集合从用户态拷贝到内核态,这个开销在 fd 很多时会很大;
对 socket 扫描是线性扫描,采用轮询的方法,效率较低(高并发)
epoll
epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。所以我们说epoll实际上是**事件驱动(每个事件关联上fd)**的,此时我们对这些流的操作都是有意义的。(复杂度降低到了O(1))
epoll函数接口
当某一进程调用epoll_create方法时,Linux内核会创建一个eventpoll结构体,这个结构体中有两个成员与epoll的使用方式密切相关。eventpoll结构体如下所示:
当调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可。如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户。
可知:通过红黑树和双链表数据结构,并结合回调机制,造就了epoll的高效。
一句话描述就是:三步曲。
原文:https://www.cnblogs.com/Jaffer1999/p/14771049.html