网站开发需求分析模板,英语写作网站,个人做理财网站好,建个公司网站要多少钱✨✨✨学习的道路很枯燥#xff0c;希望我们能并肩走下来! 文章目录 目录
文章目录
前言
一 冯诺依曼体系结构
二 操作系统(Operator System#xff09; 2.1 概念
2.2 设计OS的目的
编辑 2.3 OS如何进行管理
编辑2.4 总结
三 进程的标示符
3.1 基本概念… ✨✨✨学习的道路很枯燥希望我们能并肩走下来! 文章目录 目录
文章目录
前言
一 冯诺依曼体系结构
二 操作系统(Operator System 2.1 概念
2.2 设计OS的目的
编辑 2.3 OS如何进行管理
编辑2.4 总结
三 进程的标示符
3.1 基本概念
3.2 查看进程
3.2.1 ps ajx指令查看所有进程
3.2.2 /proc
编辑3.3 通过系统调用获取进程标示符
3.3.1 系统调用接口getpid 和getppid
编辑 3.2.2 理解ppid
3.4 通过系统调用创建进程-fork重要
四 进程的状态
4.1 进程的状态
4.2 Linux中的进程状态
编辑 五 进程优先级
5.1 基本概念
5.2 PRI and NI
5.3 用top命令更改已存在进程的nice
5.4 其他概念 六 进程的调度切换
总 前言
本篇详细介绍了进一步介绍Linux中的进程让使用者对进程有更加深刻的认知而不是仅仅停留在表面更好的模拟为了更好的使用. 文章可能出现错误如有请在评论区指正让我们一起交流共同进步 一 冯诺依曼体系结构 我们常见的计算机如笔记本。我们不常见的计算机如服务器大部分都遵守冯诺依曼体系。 截至目前我们所认识的计算机都是有一个个的硬件组件组成 ◎ 输入单元包括键盘, 鼠标扫描仪, 写板等 ◎ 中央处理器(CPU)含有运算器和控制器等 ◎ 输出单元显示器打印机等 关于冯诺依曼必须强调几点 ● 这里的存储器指的是内存 不考虑缓存情况 ● 这里的CPU能且只能对内存进行读写不能访问外设(输入或输出设备) ● 外设(输入或输出设备)要输入或者输出数据也只能写入内存或者从内存中读取。 ● 一句话所有设备都只能直接和内存打交道。 对冯诺依曼的理解不能停留在概念上要深入到对软件数据流理解上请解释从你登录上qq开始和某位朋友聊天开始数据的流动过程。从你打开窗口开始给他发消息到他的到消息之后的数据流动过程。如果是在qq上发送文件呢 为什么要有内存呢提高效率降低使用成本 二 操作系统(Operator System 2.1 概念
任何计算机系统都包含一个基本的程序集合称为操作系统(OS)。笼统的理解操作系统包括 ● 内核进程管理内存管理文件管理驱动管理 ● 其他程序例如函数库shell程序等等 在后面的描述中我们认为操作系统OS就单指内核
操作系统基本都是是由C语言构成的少量汇编语句 OS的本质其实是一种对软硬件进行管理的软件
2.2 设计OS的目的 2.3 OS如何进行管理 对OS如何进行管理有很多层面的理解这里我们介绍顶层理解也方便我们在之后的学习中更容易理解 举个简单的例子 在学校里校长是我们公认的管理者我们学生是公认的被管理者可是我们大多数人却没有见过校长但是校长依旧可以把我们所有人都管理得很好 可见管理者与被管理者不需要直接接触 但是校长如何管理我们呢辅导员这时候便登场了 辅导员接受校长的决策并对学生执行决策工作校长通过辅导员了解学生但校长不会认识每一个学生那校长如何对学生进行管理呢我们知道每个人是不同的但每个人都有共同的属性姓名年龄等等 校长通过掌握学生的数据便可以管理学生我们可得管理的本质其实是对数据的管理
如果人一多了怎么办呢 总结 操作系统也同样如此 整体
2.4 总结
计算机管理硬件 1. 描述起来用struct结构体 2. 组织起来用链表或其他高效的数据结构 系统调用和库函数概念 ● 在开发角度操作系统对外会表现为一个整体但是会暴露自己的部分接口供上层开发使用这部分由操作系统提供的接口叫做系统调用。 ● 系统调用在使用上功能比较基础对用户的要求相对也比较高所以有心的开发者可以对部分系统 调用进行适度封装从而形成库有了库就很有利于更上层用户或者开发者进行二次开发。 承上启下
那在还没有学习进程之前就问大家操作系统是怎么管理进行进程管理的呢很简单先把进程描述起来再把进程组织起来
三 进程的标示符
3.1 基本概念 课本概念程序的一个执行实例正在执行的程序等 内核观点担当分配系统资源CPU时间内存的实体。 从我们现存的知识来说内核观点我们无法理解课本概念又流于表面不知原因
一图解析 ps动态调度则是在进程运行过程中根据实际情况动态地调整进程的优先级。 描述进程-PCB ● 进程信息被放在一个叫做进程控制块的数据结构中可以理解为进程属性的集合。 ● 课本上称之为PCBprocess control blockLinux操作系统下的PCB是: task_struc task_struct-PCB的一种 ● 在Linux中描述进程的结构体叫做task_struct。 ● task_struct是Linux内核的一种数据结构它会被装载到RAM(内存)里并且包含着进程的信息。 task_struct 是内存级别的操作当我们启动一个进程时在操作系统内部会自动创建一个Task_struct不会进行磁盘操作
task_ struct内容分类 ● 标示符: 描述本进程的唯一标示符用来区别其他进程。 ● 状态: 任务状态退出代码退出信号等。 ● 优先级: 相对于其他进程的优先级。 ● 程序计数器: 程序中即将被执行的下一条指令的地址。 ● 内存指针: 包括程序代码和进程相关数据的指针还有和其他进程共享的内存块的指针 ● 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子要加图CPU寄存器]。 ● IO状态信息: 包括显示的I/O请求,分配给进程的IO设备和被进程使用的文件列表。 ● 记账信息: 可能包括处理器时间总和使用的时钟数总和时间限制记账号等。 其他信息 3.2 查看进程
3.2.1 ps ajx指令查看所有进程 我们写一段代码并把它运行起来
#include stdio.h
#include sys/types.h
#include unistd.h
int main()
{while(1){printf(welcome to my blog\n);sleep(1);}return 0;
}
j接着在同一个终端输入如下命令 ps axj | head -1 ps axj | grep myproc | grep -v grep 我们给这个可执行程序写的是死循环的所以会一直运行下去但是我们可以用kill指令利用标示符强制杀死这个进程 或者直接CTRLC kill -9 进程标示符 3.2.2 /proc Linux为了方便我们查找进程相关属性把进程的属性以文件的形式显示操作系统启动时会自动扫描PCB并通过proc以文件形式展现本质是内存级别的文件他是对动态运行的所有进程的一个可视化信息
打开我们有着我们进程的PID的文件 1、其中exe说明当前进程是由哪一个路径的可执行文件加载来的
2、cwd表示的是当前进程的工作目录current work dir所以为什么你fopen出来的新文件会被默认放在当前目录这其实是由该进程的cwd决定的在代码写chdir改变当前工作目录
3.3 通过系统调用获取进程标示符 进程idPID 父进程idPPID 3.3.1 系统调用接口getpid 和getppid 3.2.2 理解ppid
什么是PPID呢我们来看看刚刚执行程序的PPID是什么进程 我们都知道其实bash是命令行解释器命令行的作用一方面是解释命令另一方面是为了阻止用户的非法操作而我们每一条指令或者是可执行程序其实都是一个进程因此我们的bash命令行其实是创建了一个子进程去执行对应的指令然后自己就可以继续去帮助别的指令创建进程这样的好处就是一旦子进程崩了并不会影响bash命令行进程处理其他的指令与我们Linxu第一节Linux的组成呼应 LinuxLinux权限理解-CSDN博客 我们会发现就是当我们重新运行程序的时候只会改变子进程的id父进程id并不会改变而当我们把机器关了重新开了的似乎父进程id却改变了这说明父进程bash命令行是在打开机器的时候就创建好的一个进程
3.4 通过系统调用创建进程-fork重要 更为重要的我们要知道fork的返回值 如果成功了会返回一个子进程的pid给父进程然后还会返回一个0给子进程如果失败返回-1给父进程没有子进程被创建 ——这说明fork有两个返回值
为了方便观察后面的结果我们先写一段代码 1 #include stdio.h2 #include sys/types.h3 #include unistd.h4 int gval 0;5 int main()6 {7 while(1)8 { 11 printf(gval: %d\n, gval);12 printf(I am a process, pid: %d, ppid: %d\n, getpid(), getppid());13 pid_t id fork();14 if(id 0)15 {16 while(1)17 {18 printf(我是父进程, pid: %d, ppid:%d, ret id: %d, gval: %d\n, getpid(), getppid(), id, gval);19 gval10;20 sleep(1);21 }22 }23 else if(id 0)24 {25 while(1)26 {27 printf(我是子进程, pid: %d, ppid:%d, ret id: %d, gval: %d\n, getpid(), getppid(), id, gval);28 gval;29 sleep(1);30 }31 }32 sleep(1);33 }34 return 0;35 }运行之后我们会发现if和else if同时在进行
问题一fork为什么要给子进程返回0给父进程返回子进程pid 因为一个父亲可以有多个子女但是一个子女只能有一个父亲即父子 1n。所以对于父进程来说他未来可能需要去控制子进程所以就需要对应子进程的PID用来标定子进程的唯一性。而子进程只需要用getppid就知道其父进程了所以我们返回个0就可以了
问题二fork函数如何起到作用如何有两个返回值
因为fork函数会创建一个子进程而进程内核数据结构task_struct程序的代码和数据 父子进程代码共享数据各自开辟空间私有一份采用写时拷贝
父子的代码是共享的所以return id也是属于代码父子在被调度运行的时候各自会运行一次return因此父子进程各返回了一次
问题三 一个变量为什么会有不同的内容 暂定
四 进程的状态
4.1 进程的状态
在不同的操作系统下进程的具体状态时有差别的但普遍遵循如下规则 一图解析 运行时挂起风险大一般不用
挂起一般是在内存严重不足的时候OS会将未处在调度队列的进程的代码和数据存入磁盘的swap分区进行IO操作速度慢等到进程要使用时再从swap分区中换入
4.2 Linux中的进程状态
看看Linux内核源代码怎么说 为了弄明白正在运行的进程是什么意思我们需要知道进程的不同状态。一个进程可以有几个状态在 Linux内核里进程有时候也叫做任务。 下面的状态在kernel源代码里定义 /*
* The task state array is a strange bitmap of
* reasons to sleep. Thus running is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
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 */
}; ● R运行状态running: 并不意味着进程一定在运行中它表明进程要么是在运行中要么在运行队列 里。 ● S睡眠状态sleeping): 意味着进程在等待事件完成这里的睡眠有时候也叫做可中断睡眠 interruptible sleep。 ● D磁盘休眠状态Disk sleep有时候也叫不可中断睡眠状态uninterruptible sleep在这个状态的 进程通常会等待IO的结束。 ● T停止状态stopped 可以通过发送 SIGSTOP 信号给进程来停止T进程。这个被暂停的进程可 以通过发送 SIGCONT 信号让进程继续运行。此时程序转到后台运行只能用kill停止 ● X死亡状态dead这个状态只是一个返回状态你不会在任务列表里看到这个状态。 我们写一个死循环代码并让他运行起来
#includestdio.h
int main()
{while(1){printf(hello\n);}return 0;
} 为什么进程显示S因为对于一个进程的时间片是很短的 printf并不是直接往显示器上打的它是往内存里写的相当于显示器也有自己的缓存显示器缓存很容易被写满你的显示器并不是时时刻刻就绪的IO操作很耗费时间在CPU调度的时候外设不一定就绪大部分处于S状态可能偶尔出现R状态 健康的操作系统一般不会出现D状态因为D状态是瞬时的很难被查到 D状态——系统中有高IO几百G或者磁盘响应过慢老化空间不足 长时间等待IO过程若一直处于D则可能IO磁盘出现问题操作系统离挂掉不远了 在可执行文件后面加一个可使程序后台运行 Z(zombie)-僵尸进程 僵死状态Zombies是一个比较特殊的状态。当进程退出并且父进程使用wait()系统调用,后面讲 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 僵死进程会以终止状态保持在进程表中并且会一直在等待父进程读取退出状态代码。 所以只要子进程退出父进程还在运行但父进程没有读取子进程状态子进程进入Z状态 echo 显示最近一个程序执行时的退出信息 孤儿进程
父进程先退出子进程就称之为“孤儿进程”
孤儿进程被1号init进程领养当然要有init进程回收喽
#include stdio.h
#include unistd.h
#include stdlib.h
int main()
{pid_t id fork();if(id 0){perror(fork);return 1;}else if(id 0){//childprintf(I am child, pid : %d\n, getpid());sleep(10);}else{//parentprintf(I am parent, pid: %d\n, getpid());sleep(3);exit(0);}return 0;
} 五 进程优先级
5.1 基本概念 ● cpu资源分配的先后顺序就是指进程的优先权priority。 ● 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用可以改善系统性能 ● 还可以把进程运行到指定的CPU上这样一来把不重要的进程安排到某个CPU可以大大改善系统整体性能。 查看系统进程
在linux或者unix系统中用ps –l命令则会类似输出以下几个内容 5.2 PRI and NI ● PRI也还是比较好理解的即进程的优先级或者通俗点说就是程序被CPU执行的先后顺序此值越小 进程的优先级别越高 ● 那NI呢?就是我们所要说的nice值了其表示进程可被执行的优先级的修正数值 ● PRI值越小越快被执行那么加入nice值后将会使得PRI变为PRI(new)PRI(old)nice ● 这样当nice值为负值的时候那么该程序将会优先级值将变小即其优先级会变高则其越快被执行 所以调整进程优先级在Linux下就是调整进程nice值 ● nice其取值范围是-20至19一共40个级别。 可以理解nice值是进程优先级的修正修正数据
5.3 用top命令更改已存在进程的nice ● top ● 进入top后按“r”–输入进程PID–输入nice值 为什么进程优先级的范围 只有【6099】呢这要等我我们深入学习进程调度算法再解释
5.4 其他概念 ● 竞争性: 系统进程数目众多而CPU资源只有少量甚至1个所以进程之间是具有竞争属性的。为了高 效完成任务更合理竞争相关资源便具有了优先级 ● 独立性: 多进程运行需要独享各种资源多进程运行期间互不干扰 ● 并行: 多个进程在多个CPU下分别同时进行运行这称之为并行 ● 并发: 多个进程在一个CPU下采用进程切换的方式在一段时间之内让多个进程都得以推进称之为 并发 六 进程的调度切换
我们知道Linxu是分时操作系统根据进程的时间片对进程进行调度 上图为早期的Linux内核
当代计算机对上下文数据保护设计已经非常复杂了被放在操作系统的一个段叫TSS为了方便理解我们认为他在task_struct
总结
✨✨✨各位读友本篇分享到内容是否更好的让你理解进程的概念如果对你有帮助给个赞鼓励一下吧 世上没有绝望的处境只有对处境绝望的人。 感谢每一位一起走到这的伙伴我们可以一起交流进步一起加油吧