Linux 进程手撕笔记——万字深剖详解_linux的process(2)

最全的Linux教程,Linux从入门到精通

======================

  1. linux从入门到精通(第2版)

  2. Linux系统移植

  3. Linux驱动开发入门与实战

  4. LINUX 系统移植 第2版

  5. Linux开源网络全栈详解 从DPDK到OpenFlow

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。

需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!


在这里插入图片描述
前文属于正文的铺垫,因为比较抽象所以写了一点铺垫,觉得啰嗦的可以直接跳到 “ 进程 ”。

冯.诺依曼体系🤔

冯诺依曼这个名字估计多少都听过一点,这位著名的数学家提出了历史上著名的冯诺依曼体系:

在这里插入图片描述
他把计算机硬件分为了五大单元:输入,输出,控制器,运算器,存储器

社会是由人为基础构建的社会,人拍的抖音会给人看,万物根源是从哪里来到哪里去,输入输出的本义就是在连接两个独立的对象——人和计算机。比如键盘,话筒,摄像头这些输入;显示器,磁盘,网卡这些输出;运算器 + 控制器其实就是我们的 CPU ,存储器就是内存。

内存🤔

那么经典问题就来了,冯诺依曼体系下为什么要有内存?

首先,从技术角度 CPU 运行速度 > 寄存器速度 > 三级缓存(L1~L3 Cache )> 内存 > > 外设(磁盘) >> 光盘 。 这里每一个体之间差别是非常大的,甚至两者之间可以差一个单位量级。从图上看我们内存在数据角度上占据了体系的主导地位,而外设效率低速度慢,因此外设不和 CPU 直接交互,而是和内存交互,内存并不会读取数据,读取数据在外设完成然后将数据刷新回内存。

在我们看来, 内存就是体系下的一个大缓存,可以适配 CPU 和外设速度不均的问题;同时在也支持了数据加载到内存和数据的计算的并行,其实操作系统会提前将数据预加载到内存中,比如开机的那段等待时间就是在把操作系统预加载到内存中。

预加载的理论依据就是局部性原理,通俗一点就是我会将正在执行的代码附近的代码也提前加载进来,效率也就会嘎嘎提高了。

其次从成本角度虽然内存造价 > 外设磁盘,但是如今计算机已经走进全球寻常百姓家中,那就说明它是有效且便宜的,

控制器🤔

为什么我要掰开 CPU 来单独讲控制器呢?因为计算器大家都懂嘛,就算数运算+逻辑运算。

那控制器是搞毛的?我们说外设和 CPU 交互依靠内存,虽然外设和 CPU 在数据上没有交互,但是数据是否在输入设备上导入完成,预加载是否完成,这些问题都需要控制器进行交互,而且具体的指挥也是在 CPU 里面,控制器会直接和内存沟通,比如数据什么时候流向我 CPU?流多少过来?

但是记住几乎所有硬件都是被动配合的,一般需要配合软件才能完成某项功能(OS+CPU)

如何搞管理🤔

操作系统是一款软件,搞管理的软件,那么什么叫做管理呢?

计算机就像人一样,做事都有两步:决策和执行,在人身上这两步是一体的,但是对于计算机它是相对独立的,管理的本质不是对管理对象进行直接管理,而是拿到管理对象的所有相关数据,这种管理模式可以折射到人身上:

比如你和你学校,你学校也在管理你,但是并不是直接管理,而是通过辅导员提供的绩点,出勤率,学分等数据,来判断期末是给你发奖学金还是找你单独谈话。学校如同管理者,一个辅导员如同执行者,而学生就是被管理对象;这三者在计算机里其实就是操作系统,驱动和硬件三者的关系

数据是有多少的分别的,我们对于管理的第二层理解就是如何管理好大量的数据?

请记住六个字:先描述,再组织

想想我们人是如何认识世界的?是通过属性,告诉你你用什么来吃饭写字,你就知道是手,这就是属性。记得之前我写进博客的那句话:一切皆对象,啊不是那个对象(反正我是没有),说人话就是一切事物可以通过抽取对象的属性来达到描述对象的目的。面向对象的诞生也是必然的,因为他符合我们人认识事物的方式。

所以我们对数据的管理根据我们认识事物的方式,会变成对数据结构的管理。比如我们面对成千上万的同学,假如我就是校长,我肯定会去想有没有一种数据结构,能满足我来描述他们?于是乎,对学生信息的管理就变成了对链表的增删查改!

进程🤔

主角登场,在操作系统中有四大管理:内存管理,进程管理,文件管理和驱动管理,我们今天主要讲进程。

在书里面你可能看到:进程是一个运行起来的程序。这句话就是个废话文学,进程和程序又有什么区别?问个问题,程序是文件吗?是的,我在 Linux 开篇也说过,这个文件他就放在磁盘。每一个 exe 执行文件都放在内存了,当你打开你的任务管理器你会发现有一堆的进程:

在这里插入图片描述
我们知道了操作系统里可能存在大量进程,那么操作系统也是需要将所以的进程进行管理的,根据我们上面的理念,对进程的管理也是先描述再组织的数据管理,类比一下学生信息,进程会被放进一个 task_struct 结构体进行封装,里面包含了他所有属性,但现在我们无从得知。然后再对每一个 struct 进行连接形成一个双链表,最终又变成了内核数据结构的管理!c所以进程的概念应该是:程序加载到操作系统的代码和它所对应的内核数据结构的总称就是进程

其中这个包含代码属性的结构体 task_struct 叫做 PCB ,即进程管理块,它是 Linux 内核的一种数据结构,转载在 RAM 里且携带进程信息:

在这里插入图片描述

软硬件和操作系统交互后就会以进程的方式对外提供服务,他如同一个银行,你能看到工作人员在透明的工作区,但是确实封闭的只暴露一些窗口,这就足以说明银行的中立性他不相信任何人!操作系统也是如此,他要防止少数不法分子又要给多数人提供服务,他提供的窗口就是接口形式。这个接口其实就是 C 语言,内核也是 C 语言写的,所以C语言接口给我们提供各种函数调用。

操作系统立大功🤔

OS 为什么要给我们提供服务?很简单,这种人道主义奉献是必须的他才会有意义,我们自己写的程序,是没有资格向硬件写入的,所以他涉及出来就是服务于人。

操作系统虽然提供那么多接口,但也如同银行一样,窗口有工作人员,但他们受到过专业训练,我作为使用者我可能是小白也可能是初级工程师,我又不懂该怎么办呢?银行有接待,操作系统也有,那就是图形化界面和命令行解释器,他可以具象出一个个窗口和选项给小白进行选择即可,让解释器去帮忙调用这些接口。而面对工程师就提供了== lib 这种封装好的库在操作系统上==才方便搞事情。

操作系统如何帮我们?操作系统是通过系统调用的方式对外提供接口服务,但是 Windows 和 Linux 的系统接口一样吗?答案很明显是不一样的,在 Windows 下他会选择 Windows 接口,在 Linux 下他会选择 Linux 接口,但是上层调用的函数确实一样的函数名,哎呀,这不就是多态嘛!底层差异交给库解决,我们只管写就行了,所以经常说的可移植性和跨平台性都是在库里面动的手脚。

进程查看🤔

当我在 mytest.c 中写了一个死循环:

while(1)
{
    printf("This is a process\n");
    sleep(1);
}

(我还是使用 Makefile 自动化构建了一下,但过程是一样的)我们编译运行,此时这个一直打印的程序就是一个进程。我们如何查看进程呢?

ps ajx

ps 命令是查看进程情况的命令(未截完):
在这里插入图片描述

图上的就是当前系统中所有启动的进程,我们再 grep 针对当前可执行文件进行查看:

ps axj | grep ‘exe-name’(exename 为可执行程序名)

在这里插入图片描述

我们自己写的代码,编译为可执行程序,启动之后就是一个进程,那么别人写的呢?启动之后他也是一个进程

进程的 PID 🤔

我们还有一种查看进程的方法就是 proc 目录下查看,在根目录下是有很多路径,很多我们没见过也不知道是干啥的,但是没有关系:

在这里插入图片描述
其中 proc 是内存文件系统,里面就记录了当前系统的实时进程信息,那我们进入 proc 发现里面又是一堆奇奇怪怪的东西:

在这里插入图片描述
这些蓝色数字是啥?我们引入一个新的东西:进程的 PID

每一个进程在系统中都有唯一的标识符,就像一个身份证号一样, PID 全称就是进程 id ,重新启动同一个程序会变成一个新的进程,我们依然可以针对 pid 进行 ls 查看,里面会有他的各种属性,其中我们只需要知道两个重要信息:

在这里插入图片描述
cwd 表示当前进程的工作路径,exe 表示对应可执行程序的磁盘文件。pid 和当前路径这些都是进程的内部属性,一般就会放在进程控制块 PCB 中!

获取进程 PID🤔

想知道自己程序的 pid 直接调用 getpid() 函数即可,头文件: #include<unistd.h>,定义函数为 pid_t getpid(void)

在这里插入图片描述

程序的父进程 ppid 也可以用 getppid 获取,我们多重启几次就会发现一个亮点:重启程序会重新分配进程 pid 可以理解,但是父进程为什么不会变?
在这里插入图片描述
其实父进程就是一个 bash ,几乎我们再命令行上所执行的所有指令(cmd),都是 bash 进程的子进程。

我们结束进程除了用 ctrl + c ,还可以用 kill 命令直接杀掉进程,kill 会牵扯到信号现在不做讲解。

fork🤔

代码创建子进程需要 fork() 函数,他的返回值很有意思就是给父进程返回子进程的 pid 然后给子进程返回 0,失败就返回 -1,就意味着他有两个返回值,怪诶。可为什么是这样的呢?

我们知道一个父亲可以有很多儿子,在这个背景下父进程必须要有标识子进程的方案,就像父亲面对几个儿子喊一声儿子,这时候不知道喊的谁就会全部跑过来,因此 fork 之后就需要给父进程返回子进程 pid。

而子进程最重要的就是知道自己是否被创建成功,因为子进程他只有一个父进程,直接 getppid 就能得到,所以他找父进程的成本非常低,所以就没必要返回喽给个 0 即可。

在这里插入图片描述

那 fork 为什么能返回两次?子进程的控制块的内部数据基本上是从父亲哪里继承下来的,也不是全部,起码 pid 是自己的,子进程的代码也是父进程的,在 fork之后 ,父进程和子进程代码共享但是数据私有!因为不同的返回值,让不同的进程可以执行不同的代码。

如果一个程序调用一个函数,但这个函数准备 return 了是不是意味着核心功能已经完成? 答案是是的,return 就代表着此时子进程已经被创建,而且已经将子进程放进了运行队列,这就又要说一说进程的运行。

那又该如何理解进程被运行?在 Linux 内核中每一个 CPU 都会存在一个叫作运行队列的东西,他将存有代码和数据的结构体 task_struct 以链表形式存进队列里面, head 指针指向运行队列,然后会有一个专门调用代码的调度器来调用其中合适的进程放到 CPU 上去运行,这样就能运行一个进程。

进程状态🤔

在 task_struct 中会包含进程的状态信息,进程的状态是用整数来表示的:

在这里插入图片描述
在这里插入图片描述

运行状态有四种:运行态,终止态,阻塞态,挂起态。

运行态:不是指正在运行的进程,进程只要在运行队列中就叫做运行态,代表他已经准备好随时被调度了。

终止态:不是指该进程已经被释放,而是该进程还在但是永远不会运行,随时等待被释放。

那么问题来了,进程不运行了为什么不立马释放却要维持一个所谓的终止态?那么思考一下,释放是否需要花时间?是的,那有没有可能当前系统他抽不身来释放呢?是可能的。

阻塞态:一个进程使用资源的时候,不仅仅是在 CPU 中申请资源,可能会需要磁盘,网卡,显示器等资源。如果我们申请 CPU 资源,如果暂时无法得到满足,需要进行排队也就是加入运行队列,或者说申请其他慢设备的资源也会需要排队。

以上状态都是 task_struct 在进程排队,以此我们再推导,我们 CPU 处理多个进程可能一秒十几个,但是对于许多速度慢的外设就很恼火了,根据冯诺依曼体系,外设速度慢 CPU 块因此内存在其体系核心地位进行协调。因此,当进程访问某些资源时,该资源暂时没有准备好,或者还在为其他进程提供服务,那么当前进程就需要先从运行队列移除并将进程放入对应设备的描述结构体中的等待队列进行排队。

struct _div //某设备的描述结构体
{
//该设备属性(频率,速度等)
task_struct *wait_queue (等待队列)
}

进程在等待外部资源的时候,该进程的代码就不会被执行,这个状态就被视为进程卡住了,也就是我们所谓的进程阻塞!

挂起态挂起态其实和阻塞态有一点类似,但是更恶心,对于挂起我们首要面对的问题就是内存不足了该怎么办?要明白计算机里面 99.99% 的内存不足都是进程导致的,轻者其他程序无法运行,重者操作系统自己无法工作,所以操作系统对进程的管理又能体现了,他会帮我们进行辗转腾挪。

假设此时等待队列已经爆满,排到了二三十个进程之外了,后面的短时间内是无法被调度的,但是此时他的 PCB 和数据仍然在内存中占着茅坑不拉屎,内存告急时操作系统就会将该进程的代码和数据置换到磁盘上,这样的进程就被称为进程挂起。

所以往往在内存不足时,我们的磁盘就会发生高频率访问。

Linux 进程状态🤔

操作系统它是计算机学科的哲学,单说操作系统的教材,书籍,文章,并没有指明是 Linux 还是 Windows 还是移动端,所以大部分情况他会让结论满足各种平台,所以我们需要站在 Linux 角度去具体理解。

在这里插入图片描述

也就是说一个程序不访问显示器等外设,只访问 CPU 且处于运行状态,那么这个进程就是 R 运行态,一访问外设了即便一个 printf 都会呈现 S 阻塞态,说明他肯定在等待某种资源。而我们这里的 S 状态也叫做浅度睡眠或者可中断睡眠,他随时可以被调度唤醒。

D 状态也是一种阻塞状态,也是去等待某种资源,D 全称是 disk sleep ,Linux 中等待的是资源如果是磁盘资源,那么我们所处的状态就是 D 状态!这个状态有些人一辈子见不到,系统开发倒是很常见,一般服务器压力过大时,大部分闪退不是电脑问题,而是操作系统自动杀掉了进程,但是有些重要进程数据要是丢了该找谁背锅?操作系统还是磁盘?由此就诞生出了连操作系统都无权生杀的 D 状态进程。

要想终止 D 进程,关机是没有用的,唯一的办法就是拔掉电源。

Z 状态,z 即 zombie,僵尸状态,当 Linux 中一个进程退出时,一般不会立刻进入 X 状况(死亡状态,资源可立即回收),而是先进入 Z 状态。为什么呢?

首先要知道为什么进程会被创建?我们进程的创建就是为了完成任务,为了得知完成情况,我们是需要将进程的执行结果告知操作系统或者父进程,所以维护 Z 状态就是为了让父进程和 OS 来读取执行结果。

我们可以自己模拟一个僵尸进程:

   int main()
  {
    pid\_t id = fork();
    if(id==0)


为了做好运维面试路上的助攻手,特整理了上百道 **【运维技术栈面试题集锦】** ,让你面试不慌心不跳,高薪offer怀里抱!

这次整理的面试题,**小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。**

![](https://img-blog.csdnimg.cn/img_convert/8cfcceca84f9702d78ee7b93ff7b767c.png)

本份面试集锦涵盖了

*   **174 道运维工程师面试题**
*   **128道k8s面试题**
*   **108道shell脚本面试题**
*   **200道Linux面试题**
*   **51道docker面试题**
*   **35道Jenkis面试题**
*   **78道MongoDB面试题**
*   **17道ansible面试题**
*   **60道dubbo面试题**
*   **53道kafka面试**
*   **18道mysql面试题**
*   **40道nginx面试题**
*   **77道redis面试题**
*   **28道zookeeper**

**总计 1000+ 道面试题, 内容 又全含金量又高**

*   **174道运维工程师面试题**

> 1、什么是运维?

> 2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?

> 3、现在给你三百台服务器,你怎么对他们进行管理?

> 4、简述raid0 raid1raid5二种工作模式的工作原理及特点

> 5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?

> 6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?

> 7、Tomcat和Resin有什么区别,工作中你怎么选择?

> 8、什么是中间件?什么是jdk?

> 9、讲述一下Tomcat8005、8009、8080三个端口的含义?

> 10、什么叫CDN?

> 11、什么叫网站灰度发布?

> 12、简述DNS进行域名解析的过程?

> 13、RabbitMQ是什么东西?

> 14、讲一下Keepalived的工作原理?

> 15、讲述一下LVS三种模式的工作过程?

> 16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

> 17、如何重置mysql root密码?

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

> 11、什么叫网站灰度发布?

> 12、简述DNS进行域名解析的过程?

> 13、RabbitMQ是什么东西?

> 14、讲一下Keepalived的工作原理?

> 15、讲述一下LVS三种模式的工作过程?

> 16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

> 17、如何重置mysql root密码?

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值