计算机系统中最著名的冯诺依曼体系包括输入输出设备、cpu、存储器。
1.cpu:cpu作为计算机的运算中心主要工作就是完成一些运算,在我们现在的生活中一台设备中会包含不止一个cpu,与此同时cpu也具有一定的存储功能,但是存储量很小,cpu中的寄存器就发挥着这样的作用,他们的特点是空间小、访问快。
2.存储器
①内存:
存储大小相对外存小,cpu可以直接访问、速度快、断电后数据不会被保存
②外存:
存储空间相对于内存大、cpu不能直接访问,必须要先加载到内存中才能访问、访问速度慢、断电后数据会被保存
比如说有一个可执行程序,那么实际上它是在外存中存放的,只有在执行它的时候才会被加载到内存,这个时候如果我们删除它是不会影响它的执行的。
那么什么又是操作系统呢?
我们讨论的Linux就是一个操作系统,简单来说就是一个管理硬件和软件资源的东西。我们可以用一张图来理解一下:
通过这张图我们可以将这些部分简单的分成三个部分:用户接口即用户部分、系统调用操作系统以及驱动程序代表的是系统软件部分、底层硬件即硬件部分,从这个图我们就可以看到操作系统是怎么将软硬件和用户部分管理起来的,它其实就是起着一个桥梁的作用。
同样我们也要理解系统调用和库函数的概念:
在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。
所以,计算机管理硬件就是通过描述加组织的方式
那么什么是进程呢?简单来说就是程序执行的实例,站在系统的角度进程就是分配系统资源的实体,我们一打开机器就会启动很多进程。我们在Windows中可以启动任务管理器来查看进程,在Linux中可以用指令ps(aux)或top查看进程,进程的管理也是通过描述(结构体)加组织(双向链表),我们下面详细讨论。
描述进程
在Linux中描述进程是将其信息放在一个结构体中(task_struct),我们通常叫它PCB,这个结构体内的内容有:
- 进程标识符(进程号)
- 内存指针:包括程序代码和进程数据的指针,告诉进程代码/数据在内存中的位置
- 状态:进程的状态
- 上下文信息:进程执行时处理器的寄存器中的数据
- 优先级:相对于其他进程的优先级
- 程序计数器:程序即将被执行的下一条指令的地址
- 记账信息:进程在cpu上执行了多久的时间统计
我们详细讨论一下这些信息:
1.进程号唯一标识一个进程,就像人的身份证号码,进程号与进程一一对应。可以在代码中通过getpid()/getppid()这两个函数获取自身进程号和其父进程号。
2.进程状态有
①:R(就绪状态)
在就绪状态队列中,不一定是在运行
②:S(睡眠状态)
进程在等待事件完成,代码中可以使用sleep来模拟出这个状态
③:D(深度睡眠状态)
也可以叫磁盘休眠状态,这个时候通常是进行大规模IO操作时
④:T(停止状态)
⑤:t(跟踪状态)
在调试时会是这个状态
⑥:Z(僵尸状态)
a.产生原因
当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸进程。僵尸进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态,比如可以在让父进程休眠而让子进程什么都不做直接退出,此时的子进程就是僵尸进程。
b.解决方式:
而僵尸进程是无法用kill指令杀掉的,只有让其父进程退出(回收掉子进程的资源)子进程才会退出,但这是种非常暴力的做法,我们通常是在父进程使用wait函数来等待子进程退出再执行父进程后续的逻辑,这样就很好的的避免了僵尸进程。
c.僵尸进程的危害
想象一下一个父进程创建出很多子进程而不去回收,这个子进程会开辟空间占用内存,就会导致内存的浪费,进而导致内存泄露。
进程状态大致就这么多吗,但有一种特殊的进程叫做孤儿进程,如果父进程提前退出而子进程还在运行,此时的子进程就被叫做孤儿进程,那么回收它的将不是它的父进程,而是由一号进程(init)领养回收。
3.进程优先级
进程在运行时分为并行式和并发式两种,并行指的多个进程在多个CPU下分别,同时进行运行;并发指的时一个cpu执同时行多个进程(一会儿执行这个,一会儿执行那个),显然并发式的执行方式更加普遍,毕竟一个进程配置一个cpu的话造价贵嘛,所以程序优先级记录的就是进程执行的先后顺序,比如某一进程执行时间长而某一进程执行时间段,不如将时间段的这个进程优先级提高,毕竟它也要想用资源嘛。
使用ps -l这个命令可以显示进程的信息,PRI所对应的就是这个进程的优先级,值越小代表优先级越高,NI对应的值代表修正值,真实优先级就是PRI+NI 后的值。
环境变量
什么是环境变量呢?我们可以将环境变量理解为系统的视线范围,当程序配置进环境变量时就进入了系统的视线范围。
环境变量可以通过env命令去查看,也可以通过echo $去查看具体某个环境变量的值,每个程序都有一张环境变量表,这个环境表是资格字符指针数组,以NULL 结尾,里面保存的就是环境变量的信息(以键值对保存)。
虚拟地址空间是通过页表这样的结构映射到对应的物理存储空间,物理地址用户一般看不到,由系统进行管理。
原文地址:https://blog.51cto.com/14239789/2466099