【Linux】——进程概念(万字解读)_linux进程
一冯诺依曼体系结构
在此之前,我们先要理解我们计算机的冯诺依曼体系结构,因为是进程的基础
我们所有的操作其实都是基于这样一个模型,比如你在qq上,和别人发送消息,这个消息肯定是先通过输入设备进行输入,输入到存储器(这里只是单指内存),然后通过控制器和运算器的控制和计算,把消息发送到输出设备(这里可以是网卡和显示器)
那我们这些操作肯定需要有人控制吧,没有人控制,单凭一个cpu能去接受这么多信息?别完了,cpu的运行速度是很快的,如果这些事情都要他去处理,那就没有那么高效了。
所有我们引出了操作系统这个概念
二 操作系统
概念
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
内核(进程管理,内存管理,文件管理,驱动管理)
其他程序(例如函数库,shell程序等等)
设计OS的目的
与硬件交互,管理所有的软硬件资源
为用户程序(应用程序)提供一个良好的执行环境
定位
在整个计算机软硬件架构中,操作系统的定位是:一款纯正的“搞管理”的软件
由于我们的文件和进程错综复杂,都会占据内存,同时也有谁先进行谁后进行的顺序,所以这里我们需要一个管理者去管理好这些资源,不然我们的电脑用几下就会导致死机,所以我们开机第一个启动的软件就是操作系统这个系统软件
管理
那我们操作系统是用什么方式去管理这些资源的呢??
这张图表示了我们在进行操作的轮廓图,操作系统在管理底层的硬件的时候,并不能直接去访问,而是应该经过驱动程序间接访问,所以操作系统在管理硬件资源的时候,只是拿到了硬件的数据,并没有直接见到了底层的硬件,既然我们拿到了数据,我们就可以通过数据去判断这个硬件程序是否需要关闭,当然这些数据太多了,而且有些属于一个类型,有些不是,那既然这样,我们就可以通过描述这个硬件的基本属性,同时加上他的数据,这样归纳起来就可以统一管理了,但是这么多硬件,怎么去找呢??创建一个双链表,一个红黑树?把他们管理起来?,可行!!
所以经过以上步骤就形成了一个先描述,再组织的操作
之前说了,只能从上到下访问,那我们电脑上的软件有各种功能,这些功能直接或者间接的操作了我们操作系统,那是不是这些软件可以肆意妄为??并不是!操作系统会防止用户去乱动操作系统里面的东西,但是它又得让用户去访问,于是就有了系统调用这个概念,由于系统调用的存在,使得我们可以在电脑上开发各种应用,使得我们的电脑功能性更全,这种选择性提供也是操作系统管理的一种手段
总结
计算机管理硬件,先用struct结构体描述,再用多种数据结构进行组织,这里为什么是struct呢?因为linux是用c语言写的。
系统调用和库函数概念
在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。
三 进程
有了上面的认识,我们就可以再来认识进程的概念,一个进程也就是我们所运行的程序,一个qq,一个微信,或者一个英雄联盟,他们都属于进程
所以一句话概括就是进程就是用来吃系统资源的——担当分配系统资源(CPU时间,内存)的实体。
进程也是受操作系统所管理的,那操作系统怎么管理?,和上面一样——先描述再组织
描述进程
对于进程我们得先描述。进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct
这个PCB里面就包含了进程的诸多信息,比如:优先级,上下文数据,指针之类的
在linux下的PCB——task_struct
✨标示符: 描述本进程的唯一标示符,用来区别其他进程。
✨状态: 任务状态,退出代码,退出信号等。
✨优先级: 相对于其他进程的优先级。
✨程序计数器: 程序中即将被执行的下一条指令的地址。
✨内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
✨上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
✨I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
✨记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
✨其他信息
组织进程
所有运行在系统里的进程都以task_struct链表的形式存在内核里。
查看进程
查看一个进程,查看的是进程的信息
我们可以通过 ls /proc这个指令查看所有进程的信息
如果我们现在运行一个程序
如果我们想看他的信息,那么我们就使用一个看起来比较直观的命令(ps/top),因为/proc这个指令可能看起来并不直观,因为/proc目录下的文件和目录提供的是系统的底层信息,它们的内容通常是以文本形式展示的,但格式和结构可能相对复杂。
这里我们使用ps查看,我们先运行这个程序
这里可能查看到三个进程,但是只有第一个是我们要查的,其他两个是因为我们输入的指令也是一个进程,所以也把他们的进程信息输出了
这就是进程的pid也就是进程的标识符,linux也是通过这个去区分进程的不同的
除了这种方法可以获取进程的pid,我们还可以通用系统调用去查看;
通过系统调用获取进程标示符
#include #include #includeint main(){ printf(\"pid:%d\\n\",getpid()); return 0;}
通过这段代码就可以获取到该进程的pid
运行这段程序就可以获得该进程的pid,但是我们注意到其实他还有一个表示符
这一段是他们的父进程的pid,也就是ppid,每个子进程都有一个父进程,当然,最大的父亲就是我们的bash
我们也可以通过系统调用把他的ppid也打印出来
#include #include #includeint main(){ printf(\"pid:%d ppid:%d\\n\",getpid(),getppid()); return 0;}
通过系统调用创建进程-fork初识
对于fork也是一个系统调用,他的作用就是创建一个子进程
#include #include #include int main(){ int ret = fork(); if(ret < 0) { perror(\"fork\"); return 1; } else if(ret == 0) { //child printf(\"I am child : %d!, ret: %d\\n\", getpid(), ret); } else { //father printf(\"I am father : %d!, ret: %d\\n\", getpid(), ret); } sl