前言
作者:小蜗牛向前冲
名言:我可以接受失败,但我不能接受放弃
如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。
目录
本期学习目标:认识冯诺依曼体系结构,认识什么是操作系统,什么是进程。
对于一个计算机的计算机硬件系统五大部件由运算器、控制器、存储器、输入设备、输出设备组成:
在我们所认识的计算机,都有那些硬件组成:
输入单元:键盘,鼠标,扫描器,写板等
中央处理器(cpu):包含运算器和控制器等
输出单元:显示器,打印机等
对于五大硬件中的存储器,指的其实就是计算机中的内存,对于计算机来说他有个特点:掉电易失,和CPU交互的速度非常快。
计算机中除了有内存可以存放资源,还有磁盘称外设,磁盘的特点:永久性存储能力,但和CPU交互的速度慢。
那计算机要将一个信息存储起来CPU是直接将信息放到磁盘中的吗?显然不是,我们都知道CPU是个急性子,他的运行速度很快,而磁盘是个慢性子,他存储信息只能慢慢来,如果CPU直接和他交互这将非常影响效率,所以CPU在读取和写入都是和内存打交道的。
这里简单总结一下:所以的外设有数据需要载入,只能载入到内存中,内存写出,也一定是写到外部设备中。
在前面我们在概念上理解了冯诺依曼体系结构是指的是硬件之间的联系,下面我们在从软件数据流理解,请解释,从你登录上qq开始和某位朋友聊天开始,数据的流动过程。
下面我们就以A和B的在QQ中聊天中理解,A在他的计算机的键盘中输入“你好”,那A这台计算机要做哪些工作呢?
首先应该是CPU从输入设备(键盘)中读取信息,CPU在将信息写入到内存中,在将信息通过输出设备(网卡),在由A设备的网卡向B设备的网卡(输入设备)传达信息,在由B设备的CPU放到B的内存中,最后由内存向B设备的输出设备(显示器)展示,这样就完成了对信息的传递(吧考虑网络的问题)。
从这里我们可以看从冯诺依曼体系不仅仅是对硬件有很重要,对于软件也同样重要,因为软件和硬件是相互适应的。
什么是操作系统呢?简单点来说是一个进行软件和硬件资源管理的软件
概念
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
- 内核(进程管理,内存管理,文件管理,驱动管理)
- 其他程序(例如函数库,shell程序等等
对于一台计算机来说都是必须要有一个操纵系统的,否则这台计算机将无法工作。
为什么说呢?,对于一个操纵系统来说,他对下通过合理的管理软硬件资源,来保证对上用户提供良好的(高效的,安全的)执行环境。所以说没有了操纵系统所以的工作将会发生混乱,进程管理就不知道是在什么时候进行,驱动管理会无法正常工作。
上面我们说到了操作系统是通过管理来让硬件和软件相互配合使系统正常运转,那操纵系统是如何进行管理的呢?
我们先暂且不论操纵系统是如何管理的,在日常生活中一个学校的校长是如何管理学生的,一般来说我们普通学生是和校长没有交流的机会的,但是校长却能知道我们期末挂没挂科,参加了那些比赛。这是因为校长有我们的基本信息,比如姓名,专业,期末成绩等,通过查询这些数据就能够对这个学生进行管理,通过告诉他的辅导员,提醒他要重修某门学科。
也就是说校长是通过数据对学生进行管理的。
那站在程序员的角度,校长是如何规划全学校的数据的,这就要用到数据结构,我们可定义一个类存放一个人各种信息,然后通过链表在将这些信息管理起来,这不就是先描述在组织吗?
所以说管理的本质逻辑都是在先描述后组织。
那对于应该操纵系统来,也应该是先描述在组织。
怎么理解描述呢?
其实就是操纵系统会为用户提供各种C式接口,来接受用户的各种请求。
怎么理解组织?
其实就是通过操纵系统对软件(进程管理,文件系统,内存管理,驱动管理)进行资源调配,从而通过硬件在完成用户的请求。
基本概念:
- 课本概念:程序的一个执行实例,正在执行的程序等。
- 内核观点:担当分配系统资源(CPU时间,内存)的实体。
我相信很多小伙伴看完上面的概念还是对进程的很模糊。下面我们通过一个可执行程序是如何运行起来可理解。
首先我们要明白程序的本质就是文件,也就说是存在磁盘中的。其实当我们要将文件运行起来,就要先从磁盘中取到内存中,在由内存传向CPU,但是我们要明白在内存中不仅仅是存放在可执行的代码(计算机可识别的二进制),还有一个叫做PCB(进程管理模块)的数据结构,里面存放的各种信息(给进程的所以属性,对于的代码地址和属性),而CPU从内存中拿取的数据是拿PCB的数据,如果要执行程序,就通过PCB的存放的代码信息找到可执行的程序代码在执行。
内存中不可能仅仅会有一个程序,可能会存在有多个程序要执行,那操纵系统是如何去管理?
这就要对进程进行的管理,也就可以认为是对PCB进行管理,这里也就是描述了PCB是上面,在通过对PCB组织起来去完成命令。
说了这么多,进程其实就是为了服务操作系统管理而诞生的,而他管理的场所在内存。
进程 = 内核数据结构(sask struct) + 进程对应的磁盘代码。
描述进程-PCB
- 在Linux中描述进程的结构体叫做task_struct。
- task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
sask_ struct内容分类
- 标示符: 描述本进程的唯一标示符,用来区别其他进程。
- 状态: 任务状态,退出代码,退出信号等。
- 优先级: 相对于其他进程的优先级。
- 程序计数器: 程序中即将被执行的下一条指令的地址。
- 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
- I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
- 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
- 其他信息
我们可以用这组命令来查看进程:
ps ajx | head -1 && ps ajx | grep 'test'
其中的 ps ajx就是查看进程的命令,但那是全部进程,所以要用grep进行筛选,而head -1指打印出第一行。
您我们要如何终止进程呢?
kill -9 进程地址
下面为了通过系统调用获取进程标示符,我们重新写一个程序来验证。
- #include
- #include
-
- int main()
- {
- fork();
- printf("pid:子进程%d\n",getpid());
- printf("ppid:父进程%d\n",getppid());
- return 0;
- }
这里简单解析一下代码:
fork函数能够创建一个子进程,但我们要注意fork是个函数;也就是说函数执行前就只有一个父进程,函数执行后:父进程+子进程,其中的getpid()函数是获取一个子进程,而getppid是获取一个父进程。
也就是说存在二个流,前面二行是先被打印,后二行在被打印。
这里我们要注意 fork的返回值(pid_t),如果fork函数成功调用(返回成功)会给父进程返回子进程的pid,将0返回给子进程。这里我们会感到非常震惊,一个函数的返回值居然有二个返回值,这里要解释的话就要去学习进程地址空间,这里就不多说了。