Linux:进程(1)
一、前言
在学习进程这个Linux的系统篇前,我们先了解计算机的硬件和软件·的关系和基本操作原理能更好的让我们理解进程和以后的知识
二、冯诺依曼体系结构
我们常⻅的计算机,如笔记本。我们不常⻅的计算机,如服务器,⼤部分都遵守冯诺依曼体系。
截⾄⽬前,我们所认识的计算机,都是由⼀个个的硬件组件组成
• 输⼊单元:包括键盘,⿏标,扫描仪,写板等
• 中央处理器(CPU):含有运算器和控制器等
• 输出单元:显⽰器,打印机等
问题一:为什么不直接从输入设备->CPU->输出设备,为什么要储存器呢?
1.因为输入设备和输出设备的速率是ms级的,而CPU的运算是纳米级的,两者的速度相差几十万倍,不在一个量级,直接走那样的形式的话会使整个系统彻底低效瘫痪
2.储存器是纳米级的速率,并且当断断续续的数据或零散的数据过来时可以临时储存,当凑齐一整块再给CPU运算,而不是来几个字节就去运算,减少CPU频繁与数据交互。并且整体看来也加快了整个系统的速率。
也就是说CPU只要和内存交互数据就行了!!!
下面是一些更细节的知识
三、操作系统
我们对硬件的输入有个缺点,就是要输入对应的机器码也就是二进制的数据,我们普通用户一般不了解,所以它的上层还要能把我们人输入的东西自动转化为机器码减少我们的学习成本与用户体验,所以操作系统就是做这门工作的,而且做的更多
3.1概念
任何计算机系统都包含⼀个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
• 内核(进程管理,内存管理,⽂件管理,驱动管理)
• 其他程序(例如函数库,shell程序等等)
我们对电脑手机的操作就是在使用广义上的操作系统,就是套了一层图形化界面让我们忽略了底层的指令的使用,而我们现在要讲的是狭义上的操作系统,我们要了解内核是怎么工作的才能学好Linux的系统的知识
3.2OS的目的
• 对下,与硬件交互,管理所有的软硬件资源
• 对上,为⽤⼾程序(应⽤程序)提供⼀个良好的执⾏环境
这也是我们比如在xshell中的指令的操作要经历的过程
问题二:为什么不直接用户操作接口直接调用对操作系统的相关函数接口,而是要加一个system call?
因为直接对操作系统的函数接口的使用是不安全的,因为你不知道使用者是好人还是坏人,万一他对操作系代码进行修改或者进行一些不好的操作就会使操作系统直接瘫痪,所以上层用户不允许直接与操作系统的内部函数打交道,而是价格系统调用接口,通过对内部函数的一层封装让用户调用,这样就能既保证好人的使用,也能避免坏人破环
也就是说:在整个计算机软硬件架构中,操作系统的定位是:⼀款纯正的“搞管理”的软件
问题三:如何理解"管理"二字呢?
我们操作系统的第内存对进程等的管理是靠什么东西弄在一起的呢? 答案是数据结构
类比到我们的语言层面,我们写一个程序什么扫雷、贪吃蛇,我们的首先下手步骤是什么?那肯定是先定义结构体或类呀!也就是把要得属性先定义好,然后的步骤就是在用数据结构给组织起来!整个步骤就是先描述,再组织!
承上启下
那在还没有学习进程之前,就问⼤家,操作系统是怎么管理进⾏进程管理的呢?很简单,先把进程描述起来,再把进程组织起来!
四、进程的初步了解
4.1进程的概念
进程它其实又称任务(task),所为的进程就是运行在内存中的一个个程序,我们那我们最熟悉的C语言来举例看一下过程
首先code.c通过编译器或在Linux上gcc编译->可执行程序(如.exe)->然后写入进内存(其实本质是拷贝进去)->然后组织起来->组织的数据结构+程序->进程PCB
上面说的管理程序的属性的结构体在操作系统是上就叫做PCB。
概念:
进程信息被放在⼀个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
Linux操作系统的PCB叫做task_struct
也就是进程=内核的数据结构(task_struct)+自己的程序代码和数据
4.2task_struct
内容分类:
• 标⽰符:描述本进程的唯⼀标⽰符,⽤来区别其他进程。
• 状态:任务状态,退出代码,退出信号等。
• 优先级:相对于其他进程的优先级。
• 程序计数器:程序中即将被执⾏的下⼀条指令的地址。
• 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
• 上下⽂数据:进程执⾏时处理器的寄存器中的数据[休学例⼦,要加图CPU,寄存器]。
• I∕O状态信息:包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使⽤的⽂件列表。
• 记账信息:可能包括处理器时间总和,使⽤的时钟数总和,时间限制,记账号等。
• 其他信息
• 具体详细信息后续会介绍
也就是这些都是结构体中的一个个变量或结构体,描述着进程的相关属性,下面我先简单介绍当前能初步了解的变量的简单作用
标识符
有了它才可以知道两个或多个进程是不同的进程,在task_struct中叫做pid,也就是我们不同的人是有不同身份证的,学生是用学号的不同来区分的等日常生活实例
状态
大白话就是检测当前进程在干什么,比如是在等用户用户输入数据进去,还是该进程在等被调度
优先级
具体的优先级是不清楚的(后面会细讲),但可以用常识来看吃饭排队先来的先吃后来的后吃,但Linux肯定做了优化算法的后面学了再来讲
程序计数器
比如CPU解析代码,CPU怎么知道执行到哪一行呢?通过eip(x32位)也就是程序计数器执行一行就++嘛
上下文数据
它在task_struct是一个结构体类型,程序计数器(32位的eip)就是结构体里面的,它保存着寄存器的数据,寄存器有很多类型比如建立栈帧要的esp ebp等下面的问题能很好解释它的作用
问题四:那是不是要先运行完一个程序再去运行下一个程序呢?
不是一般是当前程序运行一个时间片(很短比如10ms),他就会暂停当前进程去执行下一个进程。那怎么找到上一个进程呢?那就要通过保存的上一个进程的上下文数据,能通过保存的数据恢复到上一个进程的数据。就好比如张三大二想参军,他跟导员说明后导员就保存你的当前档案不变,也就是让他处于休学状态,等当了两年兵之后回来继续读到毕业,转化为这里的知识就是当兵时一个进程,先暂停这个进程去完成另一个进程->当兵,那通过保存的档案就能迅速知道你是大几学生什么专业->也就是通过保存的上下文数据恢复出原来的数据,然后再执行。注意:寄存器只有一套,所以想要多个进程运行就是大概这样的流程
更详细的对每一个task_struct的变量详细解释再看下篇文章!!!
