目录
操作系统是什么
设计操作系统的目的
操作系统的定位
如何理解管理
管理的本质
管理的例子
计算机的管理概念图
操作系统管理逻辑的六字真言
系统调用和库函数的概念
进程
进程的概念
什么是PCB?
PCB的主要内容
如何查看进程?
通过系统调用获取进程标识符
Linux中创建进程
认识fork
fork有两个返回值
如何实现一个变量接受两个返回值的呢?
父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
创建进程的过程概况
小结
操作系统是什么
-
在介绍进程之前,我们先回顾一下操作系统的概念:任何计算机都包含一个基本的程序集合,这个集合我们称做操作系统。宽泛的来讲,操作系统可以分为内核(进程管理、内存管理、文件管理、驱动管理)和其他程序两大部分(函数库、shell程序等)。
设计操作系统的目的
-
与硬件交互,管理所有软件资源
-
为用户程序(应用程序)提供一个良好的执行环境
操作系统的定位
-
在整个计算机体系架构中,操作系统是一款纯正的搞管理的软件,管理的是资源
如何理解管理
管理的本质
-
管理的本质实际上就是管理数据
管理的例子
-
在一个大型制造公司中,有多个部门和不同层级的管理人员。公司的管理结构可以分为高层管理层、中层管理层和基层管理层。高层管理层:由公司的CEO(首席执行官)、CFO(首席财务官)、COO(首席运营官)等组成。他们负责制定公司的战略方向、决策重要事项,并对整个公司的运营和业绩负责。中层管理层:包括各个部门的经理、主管等,他们负责执行公司制定的战略方针,管理团队成员的日常工作,协调部门间的合作与沟通,确保部门目标的达成。基层管理层:由领班、班长等组成,他们负责具体的生产、运营工作。他们需要执行中层管理层下达的任务,指导员工完成具体工作,解决实际生产过程中的问题。通过这个例子,可以清晰地展示层级管理在一个组织中的运作方式。不同层级的管理人员各自承担着不同的责任和角色,共同协作使得整个组织能够高效运转,达成既定的目标和使命。
计算机的管理概念图
操作系统管理逻辑的六字真言
-
先描述再组织
-
描述:我们在管理一个对象之前要知道它有什么属性,换到计算机当中就是用类去表示,如:学生的学号、班级、姓名,这样在学生调皮捣蛋的时候能重拳出击。
-
组织:在描述完这个对象之后,便可以将抽象的管理转变成现实的数据结构的增删查改。
系统调用和库函数的概念
-
在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
-
系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。
-
系统调用是形成库的基础
进程
进程的概念
-
程序是静态的文件,存储在磁盘上,而进程是程序在内存中的执行实例。
-
进程 = 可执行程序+PCB
什么是PCB?
-
按照上面的说法,我们要管理进程,首先就要描述进程
-
进程控制块(Process Control Block,PCB)是操作系统中用于描述和管理进程状态及相关信息的数据结构。每个正在系统中运行的进程都有一个对应的 PCB,操作系统使用 PCB 来跟踪和管理进程的执行。如此,对进程的管理便变成了对PCB的增删查改
PCB的主要内容
-
标示符: 描述本进程的唯一标示符,用来区别其他进程
-
状态: 任务状态,退出代码,退出信号等
-
优先级: 相对于其他进程的优先级
-
程序计数器: 程序中即将被执行的下一条指令的地址
-
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
-
上下文数据: 进程执行时处理器的寄存器中的数据
-
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表
-
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等
-
其他信息
如何查看进程?
-
查看/proc文件夹即可
ls /proc/
-
使用ps、top等用户级工具
ps aux | grep test | grep -v grep
通过系统调用获取进程标识符
-
进程id(PID)
-
父进程id(PPID)
#include<stdio.h>
#include <unistd.h>
int main()
{
while(1)
{
printf("i am a process my pid : %d,my father pid :%d\n",getpid(),getppid());
sleep(1);
}
}
Linux中创建进程
-
命令行中直接启动进程:启动程序的本质就是创建进程,一般是通过父进程创建的,一般使用命令行创建的进程都是bash子进程
-
通过代码来创建:使用fork函数来创建子进程,fork前只有父进程执行代码,fork之后,父子进程都执行代码
认识fork
-
使用 man 3 fork来了解fork的使用
fork有两个返回值
-
父进程中:当fork()在父进程中被调用时,fork()会返回新创建的子进程的进程ID(PID),这个 PID 就是子进程的标识符。父进程可以通过这个返回的 PID 来识别和管理其创建的子进程。
-
子进程中:在子进程中,fork()的返回值为0。这是因为子进程是父进程的副本,所以子进程中的fork()返回值为0,表示这是子进程的执行环境。
-
错误情况:如果fork()调用失败,返回值为-1,表示创建子进程失败。在这种情况下,通常会设置全局变量errno来指示具体的错误类型,比如内存不足等。
-
因此,通过检查fork()的返回值,父进程和子进程可以根据返回值来确定自己是父进程还是子进程,并进行不同的处理逻辑。这个通常使用分支语句if来实现。
如何实现一个变量接受两个返回值的呢?
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int ret = fork();
if(ret < 0)
{
perror("fork");
return 1;
}
else if(ret == 0)
{ //child
printf("I am child : %d!, ret: %d\n", getpid(), ret);
}
else
{ //father
printf("I am father : %d!, ret: %d\n", getpid(), ret);
}
sleep(1);
return 0;
}
-
执行一个程序却有两个结果
-
操作系统是通过一些寄存器做到返回值返回两次的
父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
-
fork创建子进程,系统便会多一个子进程,以父进程为模板,为子进程创建PCB,但创建的子进程没有代码和数据,目前和父进程共享代码和数据,所以fork之后,父子进程会执行一样的代码。
创建进程的过程概况
-
找到父进程的PCB
-
malloc(task_stract)
-
根据父进程的PCB,初始化子进程的PCB
-
让子进程的PCB指向父进程的代码程序数据
-
将子进程放入调度队列中,和父进程一样去排队...
-
执行完一系列操作后便返回xxx
小结
-
综上,我们知道了管理进程要先描述,再组织,所以便有了PCB用来描述进程,进程的创建方式有命令行和代码两种,使用代码创建进程时我们要用到fork函数,fork函数有两个返回值,子进程和父进程共享代码和数据,且数据以写时拷贝的形式。对于fork函数,后面会专门写一篇博客来介绍,祝同志们生活顺利、学业有成QVQ