Linux进程概念1

前言

从这篇博客开始,后面我们主要讲xshell中Linux内容,C++后续会继续补充一点
Linux基础内容我就不讲了,直接从进程开始讲

1. 进程是什么

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

像这种程序正在运行,还没有结束的过程就是一个进程,进程在电脑底部就是.exe文件中的代码拷贝到了内存中,原本是在磁盘中的,再加上创建了一个task_struct的结构体(记录进程的数据)
如何证明有这个进程呢,我们再打开一个xshell就可以找到了
在这里插入图片描述

ps ajx就是查找所有的进程,|是管道,head -1就是拿出第一行
用分号就可以在一行输入多条命令,grep就是打出含有myproc的进程
可以看出第一个就是我们运行程序的进程
第二个是因为我们使用的这个指令也是进程,打印的这个过程grep的这个过程也是进程,所以会打印出来
在这里插入图片描述
&&和分号也是同样的效果
入股不想打印出grep的进程,可以这样
在这里插入图片描述
这个就是不查找grep的意思,这个我们可以看出每一个指令在运行中也是指令,因为指令执行很快,所以我们一般看不到进程

2. 进程的pid

每个进程都有pid,这个就相当于我们学生每个人都有学号一样
getid这个函数可以获取进程的pid
在这里插入图片描述
pid_t是一个长的整型,是分装好的整型
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看出,进程在运行中,是不会改变pid的,进程结束,下一次开启进程,pid会改变
在这里插入图片描述
进程在运行中是可以杀死的
在这里插入图片描述
kill -9 加pid就可以杀死对应进程了
在这里插入图片描述
当然也可以用ctrl+c
在这里插入图片描述
查看进程相关数据,除了ps,还可以去看根目录下的proc目录,这个目录记录了所有的进程
在这里插入图片描述
对应进程的文件名就是pid
在这里插入图片描述
这其中有两个比较重要的数据,就是
在这里插入图片描述
exe就是我们运行程序.exe也就是myproc的位置
如果我们在运行中删除可执行文件的话
在这里插入图片描述
在这里插入图片描述
这里的exe就会变成这样,因为它不在那个位置了嘛
在这里插入图片描述
但是程序仍然可以运行,这是因为程序是导入了内存中的,当然结束运行,下一次肯定就不能运行了
下面讲一下CWD的作用,CWD的作用就是当前的工作目录,也就是我们fopen创建文件默认的工作路径,就是本目录
在这里插入图片描述
在这里插入图片描述
但我们可以用chdir来改变CWD,来改变当前工作目录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
CWD是改变了,但是根目录下却是test.txt文件,为什么呢,这是因为我们在更目录下没有建立文件的权限,没有w权限
换个目录就可以了
在这里插入图片描述
在这里插入图片描述
因为没有访问权限,所以P==NULL
换一个有权限的目录就可以了,比如ck
第三个我要讲的是/proc
这个目录不是磁盘级别的目录,因为这个要实时更新,必须要更新很快,而且经常更新,所以这个是内存级别的文件,只有运行的时候才会创立文件

3. ppid

ppid就是这个进程的父进程的pid,每个进程的创建都必须由父进程创建
getppid这个函数就可以获得父进程的pid
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
查一下我们就知道了,可执行程序的父进程都是bash
而且bash的pid是不会改变的
这里的bash是一个命令行解释器,就相当于xshell的外壳shell,就是linux操作系统的外壳程序shell
所以说可执行程序,命令的父进程都是bash,他们的进程都要由bash创造
一般来说,打开一个xshell就有一个bash
在这里插入图片描述
我们这里又打开了一个xshell,所以就有了两个bash

4. fork

fork的主要作用就是创建一个子进程
程序运行本身就是一个进程,然后fork就可以以这个进程在创建一个子进程
在这里插入图片描述
在这里插入图片描述
可以看出,5191就是父进程,3688就是bash,因为我这次是第二天打开的xshell,所以bash的pid不一样了
然后创建了子进程5192,所以子进程就会从创建的时候开始执行后面的代码,子进程代码的执行和父进程是一样的,执行的是相同的代码,然后他们是同时执行的
写(void)id是为了防止id没有使用而报错

这个就相当于从fork开始就开始分叉了,执行两个代码,同时执行两个相同的代码
在这里插入图片描述

在这里插入图片描述
fork是一个函数,是一个系统调用函数,如果创建成功,就会给父进程返回一个子进程的pid,给子进程返回一个0
为什么一个函数会返回两个值呢,因为fork内部函数,如果走到了return,说明就已经创建成功了,说明至少到这,就已经开始分叉了,分叉就是执行的代码是一样的,但是代码的数据不一样,比如子进程的id就是0,父进程的id就是子进程的pid
在这里插入图片描述
在这里插入图片描述
看这个就可以看出,子进程和父进程的数据都是各自是各自的
然后子进程和父进程的代码执行基本上是同时的
就是在一秒钟内,执行了父进程一步,就去看看子进程能不能执行,能的话就去执行
在这里插入图片描述
而且去查看也是两个进程
子进程也会有一个task_struct,但是子父进程的task_struct都是指向同一个内存中的代码,代码共享,数据各自一份
子父进程之间具有独立性,互不干扰
在这里插入图片描述
在vim的底行模式中,这样写就可以把文本中的所有1替换成2
在这里插入图片描述

接下来我们来编写c++程序
C++后缀为.cpp或者.cc
在这里插入图片描述
c++这样写还不行,因为待会我们要写的C++有范围for,这个是要C++11才支持的,所以还要改一下
在这里插入图片描述
这样写的话就支持C++11了,但我的是支持C++11的,所以不用写
在这里插入图片描述

在这里插入图片描述
这里再说一下,子进程的task_struct是拷贝父进程的task_struct,因为两个很相似,就是数据不一样而已,所以拷贝就拷贝呗
至于父子进程的运行逻辑是怎么样的,现在暂时不考虑

fork之后,父子进程到底谁先执行这个取自于OS(操作系统)的一个叫做调度器的东西

5. 操作系统进程状态

5.1 并行和并发

操作系统执行代码的时候,不是要把一个进程执行完毕,再去执行另一个进程,而是给每一个进程都分配一个时间(时间片),执行了这个时间片,再去执行下一个进程。。。。。。这个我们说的是CPU单核的情况下
这个就是并行,,,就是这个进程执行了之后,下次执行的时候就是另一个轮回了,所以每个继承都是比较公平的

而并发就是,多个CPU执行多个进程

5.2 时间片

时间片就是每个进程执行的时间,这个时间是很短的,所以在一段时间内,就可以执行很多个继承,在我们看来,就是同时进行的,而且不卡顿

像那种每个进程挨着挨着执行,比较公平的,就是分时操作系统
但是比如在汽车这个操作系统中,刹车这个进程的优先级就比较高,遇到危险的时候就会马上执行,所以这种叫做实时操作系统

5.3 状态

在这里插入图片描述
上面这个图就是操作系统的状态
下面我们来讲
在这里插入图片描述

CPU将一个task_struct拿到CPU中执行和在排队的过程就叫做就绪和执行过程,这两个过程是没有什么区别的,也就是运行过程
大的区域是内存,小的区域就是操作系统,操作系统在内存中
task_struct拿到CPU这个过程叫做调度
在这里插入图片描述
对硬件的管理也是一个队列
当我们的程序中有scanf的时候,task_struct就会拼接到对应的键盘struct_device后面,等待输入数据,输入了数据,task_struct就又会拼接到原来的task_struct队列后面,拼接到struct_device后面这个过程叫做阻塞
所以运行和阻塞的本质就是让不同的进程处于不同的队列中
在这里插入图片描述
当内存空间不足的时候,那么阻塞的时候,把exe文件放在内存中就有点浪费空间了,操作系统就会把exe这个文件放在磁盘中的一个swap分区中,等要用的时候,就会把这个拿出来,拿进磁盘叫做换出,拿出磁盘叫做换入,这样明显效率低,所以一般企业会禁止这个swap,而且内存没有空间了,就该更新了,,,,这个拿去swap的过程就叫做挂起,合起来叫做阻塞挂起,,,这个过程就是时间换空间
这里再补充一点task_struct也叫做PCB

6. Linux状态

static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

这个就是Linux中的状态
S是睡眠状态,R是运行状态
在这里插入图片描述
注意这里要写\n,不然的话,缓冲区无法刷新,就无法打印
在这里插入图片描述
在这里插入图片描述
这里我们可以看出,code程序的状态就是S,+我们暂时不管,S状态就是睡眠状态,为什么不是运行状态呢,因为printf是访问外设的,是去访问显示器的,所以它的task_struct就会转移到struct device,,这个状态不是运行状态,而是阻塞状态,所以说阻塞状态就是休眠状态,而非printf的代码就是运行状态了,因为访问外设的时间远大于运行的时间,所以我们看到的大多是S状态了
在这里插入图片描述
在这里插入图片描述

我们干掉printf和sleep,因为一个访问外设,一个就是真的休眠了,这样就会一直执行代码,就是运行状态了
除了printf,scanf也是一种休眠状态

D是一种深度睡眠状态,与前面的区别是什么呢,区别就是,前面的睡眠是可中断的睡眠,这个睡眠是不可中断的睡眠
什么是可中断的呢,就是你ctrl+c或者kill一下,它就真的停止运行了
而D就是kill -9也不管用
为什么这样设定呢
比如说,我们要把一堆数据,这一堆数据是很多数据,传入到磁盘中的时候,因为磁盘很慢嘛,如果我们此时终止掉程序,那么就会出现数据丢失的情况,所以我们设定D状态,让用户和操作系统都不能杀死这个程序,操作系统为什么要杀死这个程序呢,因为当内存不足的时候,操作系统就要杀死一些内存占用大的进程,所以D状态就是一种不可中断的睡眠
接下来我们来讲一下T状态,T状态就是停止状态
如果产生停止状态呢,我们只需要kill -19就可以了
在这里插入图片描述

在这里插入图片描述

就这样,就暂停了
在这里插入图片描述
kill -18就可以取消暂停状态了
在这里插入图片描述
程序就可以继续运行了
但是我们注意到这次S状态后面就没有+了,为什么呢
在这里插入图片描述
而且我们在程序运行过程中还可以执行代码
在这里插入图片描述
而且ctrl+c也无法停止,为什么呢
因为程序分为前台程序和后台程序
前台程序,我们不可以用指令,或者用了也没用,可以ctrl+c终止
暂停之后再变回来,就变为了后台程序,后台程序的话,就不能ctrl+c结束了,而且可以执行指令,只能kill-9来杀掉,这个就相当于我们在更新游戏的时候,是可以退出来的,在后台更新
至于t状态嘛,这个是跟踪暂停,这个要在调试的时候才看得到
在这里插入图片描述
这样写makefile的话,可执行程序就会增加调试信息,占用空间就会增大
在这里插入图片描述
我们这里写个脚本,这样可以一直调用ps
在这里插入图片描述

在这里插入图片描述
看这个我们就知道了,运行到断点的时候就是t状态了
在这里插入图片描述
但有些时候也是S状态,因为跳到另一个断点的过程就是运行的状态了,就不是t状态了
所以打到断点的时候就是状态t
如果被用户或者操作系统停止的话(非法但是不致命的错误),就是T

6.1main函数的返回值

接下来我们再来看一个来判断上一个函数是否正常结束的操作
在这里插入图片描述
这里我们可以看出,echo $?可以判断出上一步的指令是否正常结束
0就是正常结束
非0就是不正常结束
为什么会这样呢,这个是因为指令是用C语言写的,最后也会return 0;
只要return 0就说明是正常结束
return 其他数字就不是正常结束
所以说echo $?的这个数字就是return的数字
在这里插入图片描述
在这里插入图片描述

6.2 X与Z状态

Z状态就是僵尸状态,X状态就是死亡状态
为什么要处于僵尸状态呢,因为人在死后,法医还要看人是怎么死的,判断完后,再把人埋了,程序结束后,操作系统还要对程序进行一些处理,最后才删除
X状态就是死亡状态,这个状态一旦发生就会马上被回收处理,所以我们一般是看不到的,所以不做研究
首先讲一下,进程为什么会被创建,被创建是为了完成用户的任务的,进程结束,任务完成了吗,这个就要在僵尸状态看了,主要就是在僵尸状态看这个进程到底任务完成了没有
是要告诉父进程和OS任务到死完成了没有,然后就可以处理删除这个僵尸状态了,主要是父进程来处理僵尸
进程就是等于内核数据结构(task_struct)+代码和数据
进程退出会有退出码,这个码就是return回来的的数字,这个是会保存在task_struct中,进程退出,进入僵尸状态,代码和数据就没有用了,我们就可以看task_struct,来看任务到底完成了没有
如何查看僵尸状态呢,我们可以这样,主要是父进程处理僵尸,如果父进程什么都不干,就在那里划水,那么子进程就会一直处于僵尸状态,但是如果父进程是一个很勤奋的进程,那么一进入僵尸状态,然后就会马上处理,马上搞死,所以我们就看不到,所以我们就要设计一个懒的父进程或者很忙的父进程,让他来不及处理僵尸,这样我们就可以看到了

6.3 僵尸状态

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

在这里插入图片描述
在这里插入图片描述
可以看出子进程由S状态变为了Z状态,这个是因为父进程一直在工作,就算子进程死了,父进程也不会处理它
这个就是僵尸状态了
在这里插入图片描述

或者在子进程还没有自己死亡的时候,就杀死它,这也是个僵尸状态
处于僵尸状态的话,就会一直占用内存,也不会处理,至于父进程最终要怎么处理,这个我们要后面才说
或者我们用户怎么处理,这个要后面才说,要用一个叫做wait的东西

6.4 父进程先死

在这里插入图片描述
在这里插入图片描述
看这个我们先杀死父进程,我们就看不到父进程的僵尸状态,为什么呢,因为父进程的父进程是bash,bash是一个勤劳的进程,一旦僵尸了,就会马上处理死亡信息,然后马上宣判死刑,我们就看不到僵尸了
这时候我们还发现子进程的父进程都变成了进程1,
在这里插入图片描述
在这里插入图片描述
输入top我们就知道了,进程1就是systemd,这个是系统的进程,意思就是换爸爸了
这个爸爸也是比较勤劳的,
在这里插入图片描述
然后我们还可以看出,子进程换爸爸之后,自己就变成了后台进程
这个进程也叫做孤儿进程,因为是被领养的爸爸

7. 进程优先级

7.1 用户id

在这里插入图片描述
在讲优先级之前我们先讲用户ID
用户ID就是UID这个东西,就是1000
也就是我们ck用户的id就是1000
在这里插入图片描述
如上我们ls -ln就可以看到用户id

7.2 优先级基本概念

PRI就是优先级,NI是优先级的变化数据,也是修正数据,nice数据
意思就是,一个进程的新的优先级就是老的优先级+nice
为什么要有NI呢,这是因为万一程序在运行过程中修改优先级,就不知道怎么处理了
优先级的数字越小就代表优先级越高
下面我们来介绍一种修改优先级的方式,当然修改优先级有指令和代码两种方式,这里我们只介绍指令的方式
在这里插入图片描述
这里我们可以看出,我们程序的优先级是80,NI是0
怎么修改呢
输入top
然后r
然后输入要修改的进程的pid20626
然后输入NI
我们这里输入的是100
在这里插入图片描述
最后变成了这个,说明NI最大为19
而且值的注意的就是,一般修改了一次就不允许修改第二次了
要想修改的话,就要重新来一次了
或者我们直接sudo就可以了
再来一次我们发现NI最小是-20
而且每次修改,都会把PRI重置成80,再来计算,不会无限+,无限-的
这样做是为了把优先级控制在一个区间,防止优先级太高了,比一些必须得进程优先级还要高了就不行了
-20到19总共40个数字,为什么是40个呢,我们后面再说

7.3 进程切换

在这里插入图片描述
看这个图我们知道,程序是怎么运行的呢
首先CPU中有一个指针来控制task_struct来运行
CPU不是直接把exe文件中的汇编代码拿进来的,而是通过寄存器
pc寄存器保存当前代码的下一条代码的地址
ir来保存当前执行的代码
eax,ebx用来存值
就这样,代码就可以执行下去了

7.4 进程调度

但是,如果又有一个代码,task_struct2,又因为进程是会调度的,而且还因为寄存器只有一套,所以原来保存的数据,肯定会被覆盖掉,那么就完了
怎么解决呢
os会把这些数据,就是寄存器中的数据,也就是上下文数据,都放在内存中,就是自己所对应的task_struct中,这样就可以调度了,而且会接着上次的代码继续执行
在这里插入图片描述
在这里插入图片描述
看这个我们就知道了,task_struct中果然可以储存寄存器中的数据
但是CPU到底是怎么调度的呢,不可能真的是挨着挨着一个一个调度吧,如果这样的话,那优先级有什么用呢,所以肯定有特定的调度算法的,这样挨着挨着掉,这个是最老的cpu调度了

总结

下一篇还是接着这个讲,从CPU的调度算法开始讲

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1542523.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vscode 顶部 Command Center,minimap

目录 vscode 顶部 Command Center 设置显示步骤: minimap设置 方法一:使用设置界面 方法二:使用命令面板 方法三:编辑 settings.json 文件 左侧目录树和编辑器字体不一致: vscode 顶部 Command Center Visual Studio Code (VSCode) 中的 Command Center 是一个集中…

11年408考研真题解析-计算机网络

第一题: 解析:网络层虚电路服务和数据报服务 传输服务只有:有连接可靠和无连接不可靠两种,直接排除BC。 网络层指的是IP协议,由图二可知:运输层,网际层,网络接口层唯一有连接可靠的协…

vue3 本地windows下的字体的引用

1、先上了张效果: 2、windows 字体的路径:c:/windows/fonts/ 我们用华文行楷来测试下,先将华文行楷拷贝到/src/assets/fonts目录下。 3、然后我们来定义css: font-face {font-family: fyxk;font-style: normal;src: local(Opensan…

图结构感知的Transformer:一种新的图表示学习方法

人工智能咨询培训老师叶梓 转载标明出处 尽管图神经网络(GNNs)在处理图数据方面取得了显著成就,但它们在表达能力和捕获长距离依赖方面存在局限性。为了突破这些局限,研究者们开始探索将Transformer架构应用于图表示学习。在此基…

人工智能的前景与未来就业市场:机遇、挑战与社会影响

随着科技的飞速发展,人工智能(AI)已经逐渐渗透到我们生活的方方面面,它不仅引领着技术革新的浪潮,更在无声中重塑着我们的就业市场和社会结构。站在这个时代的交汇点上,我们不禁要问:人工智能将…

Web Components之继承

我们在使用Web Components自定义组件的时候,我们需要继承HTMLElement这个浏览器内置对象,但是如果我要一些高级封装,给组件内置一些方法的话。我们就需要使用继承的方式,在父类中实现基本功能的封装。 1 父类的封装 以下是我的继…

Java多线程(1)—线程基础

一、关于线程 1.1 简介 计算机线程(Thread)是操作系统能够进行运算调度的最小单位。线程的优势在于提高了程序的效率和响应能力,尤其在处理 I/O 操作或多任务时。多线程编程能够充分利用多核处理器的计算能力,达到更高的性能。 …

Spring 源码分析

Spring 源码版本 4.2.8.RELEASE Bean 生命周期 动态代理 代理模式 优点: 在不修改目标对象的功能前提下,能通过代理对象对目标功能扩展缺点: 代理对象需要与目标对象实现一样的接口,所以会有很多代理类,一旦接口增加方法,目标对…

Apifox 「定时任务」操作指南,解锁自动化测试的新利器

定时任务是按照预设时间自动执行的任务,它可以有效解决一些常见问题,比如频繁执行的回归测试和大规模的接口测试,这些任务需要在固定时间点或间隔周期内自动运行,以确保软件的持续集成和持续交付过程中的稳定性和可靠性。通过使用…

Windows下 批量重命名文件【bat实现】-两个小问题

Windows下 批量重命名文件【bat实现】_bat批量重命名文件ren-CSDN博客 上面是原来的教程,我遇到了两个小问题,问题及解决如下: ①dir/b>rename.csv : 无法将“dir/b>rename.csv”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。…

【每天学个新注解】Day 2 Lombok注解简解(一)—@Data、@Build、@Value

Data 相当于同时使用了 Getter 、Setter 、RequiredArgsConstructor、ToString、EqualsAndHashCode 1、如何使用 需要同时使用Getter 、Setter 、RequiredArgsConstructor、ToString、EqualsAndHashCode注解一个Bean的时候。 2、代码示例 例: Data public cla…

CCC SPAKE2+流程解析

1、SPAKE2流程及SCP03通道介绍 SPAKE2流程发生在CCC车主配对过程中的Phase2。 SPAKE2流程为车辆和手机之间的数据交换建立了一个安全通道SCP03。 那这个SCP03通道是干啥的? 我们可以先简单的理解为:建立安全通道前,车辆和手机之间交互的AP…

剖解反转链表

剖解反转链表 思路: 1.若链表为空或者只存在一个节点,就无需反转,直接返回head 2.若存在多个节点 首先将head.next给到cur,并将head.next置为null 剩余的节点就利用头插法,反转链表 class Solution {public ListNo…

基于SpringBoot+Vue+MySQL的特色旅游网站系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着旅游业的蓬勃发展,人们对旅游体验的需求日益多样化与个性化。传统的旅游信息查询与预订方式已难以满足现代游客的需求。因此,我们开发了这款基于SpringBootVueMySQL的特色旅游网站系统。该系统旨在通…

MySQL高阶1917-Leetcodify好友推荐

目录 题目 准备数据 分析数据 总结 题目 为 Leetcodify 用户推荐好友。我们将符合下列条件的用户 x 推荐给用户 y : 用户 x 和 y 不是好友,且用户 x 和 y 在同一天收听了相同的三首或更多不同歌曲。 注意,好友推荐是单向的&#xff0c…

web前端字段大小写下划线转换工具

文章目录 前言一、如何使用?二、相关代码总结 前言 程序员在敲代码的过程中都要命名一些字段,但是Java语言对字段的命名规范和sql命名规范不一样,如下图所示,这种机械性的转换工作很劳神费力,为了省点劲写了一个web小…

pdf怎么编辑修改内容?试试这四款工具!

作为一个经常探索各种办公软件的人,今天我打算和大家聊聊一个我们工作中经常会遇到的问题——编辑PDF文件。我们都知道,PDF文件以其格式稳定、不易被篡改而受到青睐,但这也意味着一旦需要修改内容,就变得相当棘手。不过&#xff0…

设计模式之类结构模式例题

答案:B A 知识点: 设计模式中类结构模式分别是:工厂方法模式,适配器模式,模板方法模式,解释器模式 记忆方法:公司里有个模特小姐姐,公是工厂模式,司是适配器模式&…

Mapper代理

文章目录 Mapper代理路径一定要写对Mapper代理方式加载配置文件 (包扫描的方式) Mapper代理 好像就是能 包名.方法。 反正就是防止硬编码,更灵活,更适用。 路径一定要写对 Mapper代理方式加载配置文件 (包扫描的方式…

fiddler抓包08_抓Android手机请求

课程大纲 手机抓包,电脑端的设置和IOS端相同,设置一次即可,无需重复设置。 前提:电脑和手机连接同一个局域网 土小帽电脑和手机都连了自己的无线网“tuxiaomao”。 Step1. 电脑端设置 ① 打开Fiddler - 开启抓包(F12…