目次
一、前言
二、正文
2.1 冯诺依曼体系结构
2.2 操作系统
2.3历程
2.3.1基本概念
2.3.2形貌历程-PCB
2.3.3构造历程
2.3.4查看历程-ps/top
2.3.5 杀掉历程-kiil
2.3.6通过系统调用获取历程标示符-getpid/getppid
2.3.7 通过系统调用创建历程-fork
一、前言
本文为小伙伴们来带来Linux中有关历程的相干知识!
二、正文
在进行历程的讲解开始之前,我们必要先给各人铺垫两个概念,分别是冯诺依曼体系结构和操作系统,即硬件和软件两个方面。
2.1 冯诺依曼体系结构
在生活中,我们常见的计算机,如条记本。我们不常见的计算机,如服务器,大部门都遵守冯诺依曼体系。那么到底什么是冯诺依曼体系呢?各人可以看下下面这幅图。
停止现在为止,我们所熟悉的计算机,都是由一个个的硬件组成
● 输入单元:包括键盘, 鼠标,扫描仪, 写板等
● 中心处理器(CPU):含有运算器和控制器等
● 输出单元:显示器,打印机等
关于冯诺依曼体系结构,必须夸大几点:
● 这里的存储器指的是内存
● 不思量缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出装备)
● 外设(输入或输出装备)要输入或者输出数据,也只能写入内存或者从内存中读取。
● 一句话,全部装备都只能直接和内存打交道
不过如果我们对冯诺依曼的明白倘若仅仅停留在概念上,是不够的。我们必要深入到对软件数据流明白上。下面我们以登上qq开始和某位朋友发消息为例来体现下冯诺依曼。
在我们向朋友发消息这一过程中,第一步是我们必要向朋友发送信息,那么首先我们就必要向键盘这一输入装备读取到要发送的信息,然后我们CPU,即中心处理器向内存中读取到信息,再写入到输出装备网卡中;第二步就是朋友必要去接受我们的信息,他必要向输入装备网卡中读取信息,再通过CPU从内存中读取到数据,最后在输出装备,即显示器上输出出来我们所发送的信息。
2.2 操作系统
冯诺依曼是硬件层面的,在软件层面我们就必要来到操作系统了。
对于操作系统,我们必要解决这三个问题,分别是:1.为什么要有操作系统 2.操作系统是什么 3.操作系统是怎么做的
★为什么要有操作系统
●操作系统可以帮助用户,管理好下面的软硬件资源
●为了为用户提供一个良好(稳定、高效、安全)的执行情况
综合以上两点,我们就可以很好的回复我们为什么要有操作系统了,因为操作系统通过管理好底层的软硬件资源(本领),为用户提供一个良好的执行情况(目的)
★操作系统是什么
操作系统是一款进行管理的软件,这里的管理既包括硬件也包括软件。
★操作系统是怎么办的,即如何进行管理
首先我们要知道全部访问操作系统的举动,都只能通过系统调用来完成,这是因为在操作系统里面会有各种各样的数据,但是操作系统不相信任何用户。就像我们去去银行存取钱,我们只必要通过前面的柜台或者存取机来达到目的, 但是具体的实验是由银行来实现的。所以操作系统为了保证自己数据的安全,同时又为了保证给用户提供服务,操作系统以接口的方式为用户提供了调用的入口,来获取操作系统内部的数据,这些接口一样平常也是用C来实现的。
然后,我们再来谈谈如何管理,所谓管理,无非是这六个字:先形貌,再构造,就拿我们之前学的C++为例,我们都知道C++是一个面向对象的语言,我们学了类和STL。通过类我们就可以形貌一个对象;通过STL中的各种容器,诸如vector,list等,我们就可以将对象构造起来。有了形貌和构造这两步之后,我们就可以很方便的进行管理了,无论是添加一个对象,删除一个对象,还是对对象中的数据进行修改就都可以很方便的实现了。而操作系统也恰恰是这么做的,它通过用struct结构体来形貌起来,再通过链表或其他更高效的数据结构来构造。
★系统调用和库函数概念
●在开发角度,操作系统对外会表现为一个整体,但是会袒露自己的部门接口,供上层开发利用,这部门 由操作系统提供的接口,叫做系统调用。
●系统调用在利用上,功能比力底子,对用户的要求相对也比力高,所以,故意的开发者可以对部门系统 调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。
2.3历程
2.3.1基本概念
●讲义概念:程序的一个执行实例,正在执行的程序等
●内核观点:继承分配系统资源(CPU时间,内存)的实体。用通俗的语言来说就是,历程=内核PCB数据结构对象+自己的代码和数据
2.3.2形貌历程-PCB
●历程信息被放在一个叫做历程控制块的数据结构中,可以明白为历程属性的聚集。
●讲义上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct
task_struct-PCB的一种
●在Linux中形貌历程的结构体叫做task_struct。
● task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里而且包罗着历程的信息
task_struct内容分类
● 标示符: 形貌本历程的唯一标示符,用来区别其他历程。
● 状态: 任务状态,退出代码,退出信号等。
● 优先级: 相对于其他历程的优先级。
● 程序计数器: 程序中即将被执行的下一条指令的地址。
● 内存指针: 包括程序代码和历程相干数据的指针,另有和其他历程共享的内存块的指针
● 上下文数据: 历程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
● I/O状态信息: 包括显示的I/O哀求,分配给历程的I/O装备和被历程利用的文件列表。
● 记账信息: 可能包括处理器时间总和,利用的时钟数总和,时间限定,记账号等。 其他信息
这些分类,我们会在后面慢慢为各人进行讲解。
2.3.3构造历程
2.3.4查看历程-ps/top
那么我们该如何去查看当前系统中有哪些历程?下面就为各人介绍两条指令
●ls /proc——历程的信息可以通过/proc这个系统文件夹来进行查看
●ps ajx
●top
当然大多数历程信息同样也可以利用top和ps这些用户级工具来获取
2.3.5 杀掉历程-kiil
●kill -9 对应历程PID
当我们偶然候遇到一个历程,我们想要去杀掉这个历程通过上面这个指令
下面给各人做个示范,首先我们先写的一个proc.c代码,在这个代码中我们会进行不停的进行打印,当这个历程开始执行后,我们该如何杀掉他呢?第一步我们先要查询到它的PID,这里我们通过ps axj | head -1 这条指令在获取历程信息的表头方便我们进行观看proc历程的对应信息,而 ps axj |grep proc 则是利用文本过滤器将我们想要的关于proc的历程筛选出来,&&则是帮助我们执行上述两条指令
不停循环打印
查询对应PID——161627
将对应历程杀死
我们可以看到当历程被杀死后会出现Killed
2.3.6通过系统调用获取历程标示符-getpid/getppid
●getpid( )
●getppid( )
打印历程信息的时候,我们会发现PID和PPID,前者是历程id,后者是父历程id。
通过上面的ps指令,我们已经可以或许获取到我们想要的任何一个历程的PID和他的父历程d的PPID,但是当们vim进入到文件的时候,就不可以或许再输入指令了,这时候我们就必要通过系统调用,即上面两个来获取PID与PPID。
就像我们平常调用printf函数的时候必要包罗头文件<stdio.h>,对于上面两个,我们也可以看作函数,因此在利用的时候也必要包罗它们的头文件,我们可以通过man指令来查询它们的手册,从而得到头文件
系统调用
2.3.7 通过系统调用创建历程-fork
●fork()
除了通过我们执行对应的指令来创建历程以外,我们还可以通过fork这个系统调用的接口来帮助我们创建历程。
同样的在利用fork,之前我们必要查询它被包罗的头文件
接下来,我们就来编写一段代码来实验一下是否有历程被我们创建出来
通过运行后,我们会发现在屏幕上一共打印了三行,而多出来的那行恰恰就是在我们创建历程之后的那部门。这使因为当我们创建历程后,在folk()之后的代码会被这两个历程执行,因此也就出现了两次打印。
既然我们乐成创建了历程,对于创建的新历程和老历程我们该如何去判断呢?别担心,对于fork()这个接口,他有两个返回值,通过手册,我们可以知道返回值是0的为子历程,而老历程则会返回原来的历程的PID
既然如许我们就能通过不同的返回值来查看这两个历程的历程信息,进一步的,我们也可以在两个历程中实现不同的操作。
我们会发现当我们利用fork接口创建新历程后,新历程是以原来的历程为父历程的。
三、结语
到此为止,关于历程(1)的讲解就告一段落了,至于历程的剩余内容会在后面的文章中进行讲解,小伙伴们敬请期待呀!
关注我 _麦麦_分享更多干货:_麦麦_-CSDN博客
各人的「关注❤️ + 点赞 |