冯诺依曼体系结构--现代计算机的硬件体系结构
输入设备、输出设备(数据输出)、存储器(数据缓冲)、运算器(数据运算)、控制器。
所有设备都是围绕存储器工作---CPU是从存储器中获取数据处理---控制器是从存储器中获取数据输出
存储器实际上是内存,为什么不是硬盘呢?--->因为硬盘的数据吞吐量太低了:机械--200MB/s
内存的数据吞吐量:是硬盘的数十倍。
内存速度快,为什么不使用内存存储数据呢?--->因为硬盘与内存的存储介质不同,内存是易失性介质,数据掉电就会丢失,而硬盘掉电后数据不会丢失。
操作系统:安装在计算机上的一个程序,管理计算机上的软硬件资源
内核(负责系统的核心功能-软件管理,硬件管理,内存管理,文件管理...)+外部应用
用户不能直接访问系统内核。操作系统会向外提供访问内核的接口---每个接口完成的功能都是固定的---系统调用接口
操作系统如何管理软硬件:先描述,再组织。
用户--->通过库函数/shell指令调用系统接口--->操作系统--->硬件驱动--->输出设备
系统调用接口:操作系统向用户提供的访问内核的接口
库函数与系统调用接口的关系:库函数封装了系统调用接口
进程概念:进程就是运行中的程序。一个程序运行起来有数据以及指令需要被CPU处理,CPU会将程序数据信息加载到内存中,然后CPU从内存中获取数据以及指令进行执行处理
CPU的分时机制:
操作系统中的进程都是同时进行的,实现系统同时运行多个程序的技术,cpu只负责执行指令,处理数据,因此操作系统的进程管理就体现出来,对程序的调度进行管理。
cpu进行程序运行处理时,每个程序会运行一段很短的时间(给一个程序分配的一个时间片),时间片运行完毕则由操作进行调度,让另一个程序的代码数据在cpu上进行处理。
只要切换的足够快,就是同时在运行。
cpu分时机制实现cpu轮询处理每一个运行中的程序,而程序运行调度由擦欧总系统进行管理。
管理思路:操作系统将每个程序运行的信息保存下来,进行调度管理的时候才知道这个程序上次运行到哪里。
对于操作系统来说,进程就是PCB,是一个程序运行的动态描述,通过PCB才能实现程序的运行调度管理。
PCB描述信息:linux下的pcb就是一个struct task_struct结构体
内存指针:能够让操作系统调度程序运行的时候,知道进程对应的指令以及数据在内存中的位置。
上下文数据:程序运行过/运行中/即将运行的数据和指令、操作调度切换进程运行的时候能够让CPU这个进程接着切换之前继续运行
程序计数器:也属于上下文数据,保存的是指令位置,切换回来知道从哪里继续执行。
标识符:能够让操作系统识别唯一的运行中的程序; IO信息、状态信息、优先级、记账信息
调度(cpu分时机制如何实现程序的切换运行):
cpu调度:分配cpu资源给进程,切换运行程序。
资源调度站:分配资源,管理资源
并发:cpu资源不够的情况下,采用CPU分时机制,任务轮询处理
并行:多核CPU上,多个进程同时占据CPU进行数据处理。
查看进程信息:ps -ef | grep ps-aux
前台进程:
进程状态:每个进程pcb都会描述一个运行的状态信息,通过状态信息,告诉操作系统进程现在该干什么。
时间片:操作系统给每个程序分配的cpu处理事件,时间片运行完了就切换到另一个程序。--->一个cpu运行处理时间段
linux对状态更加细分:
运行状态---R:包含就绪以及运行---正在运行的以及拿到时间片就能运行的称为运行状态,操作系统遇到pcb这个状态就会调度运行
可中断休眠状态---S:满足运行条件或被一些中断打断休眠之后进入运行状态
不可中断休眠状态---D:进入运行状态,不会被一些中断打断休眠状态
休眠:暂时不需要CPU调度运行,让出CPU资源,休眠也有唤醒条件,操作系统调度程序运行的时候,会查看状态,若是休眠,就会看唤醒条件是否满足,若满足,则置为运行状态进行处理,如不 满足切换下一个进程。
停止---T:停止只能手动唤醒
僵尸状态---Z:描述的是一个进程退出了,但是进程资源没有完全被释放,等待处理的一种状态。
特殊进程:
僵尸进程:处于僵尸状态的进程,退出了但是资源没有被释放的进程。
危害:造成资源泄露
产生:一个进程先于父进程退出,父进程没有关注子进程退出状态,导致子进程资源无法被完全释放,进入僵尸状态
解决:进程等待---一直关注子进程,推出了就能直接发现
进程创建:pid_t fork(void)---通过复制调用进程,创建一个新的进程
进程就是pcb,创建一个进程就是创建了一个pcb,复制调用fork的这个进程pcb的信息(内存指针、程序计数器、上下文数据)
新的进程运行的代码与调用的fork的进程一样,并且运行位置也相同
两个进程运行的程序相同“哪个是调用进程(父进程),哪个是新建进程(子进程)
在父进程中返回子进程的pid,是大于0的;在子进程中返回0; 返回-1表示创建子进程失败。
./test 运行程序,程序代码数据会被加载到内存中,操作系统创建pcb是西安对test程序运行的调度管理
为什么要创建子进程:子进程干的事情和父进程一样,当然使用返回值分流后有所不同。,有任务了创建一个子进程,让子进程去完成,出问题了崩溃的是子进程,父进程就不会崩溃,(保护父进程--分摊压力)--傀儡
fork创建子进程之后,父子进程谁先运行不一定,操作系统调度到谁谁运行
孤儿进程:父进程先于子进程退出,子进程就会称为孤儿进程;
特性:让出中断,进入系统后台运行,并且父进程称为1号进程
环境变量:终端shell中进行系统运行环境配置的变量
作用:1.可使系统环境配置更加灵活(不像修改配置文件后还得加载配置问题)。2.可通过环境变量向子进程传递数据
操作指令:env-查看所有环境变量 echo-直接打印某个变量的内容 set-查看所有变量,不止环境变量 export-声明定义转换环境变量
指令应用:echo $PATH---($表示后边的字符串是一个变量名称) export PATH=$PATH:.
注意事项:shell中的普通变量可以起到环境配置的作用,但是无法进行数据传递
典型唤醒变量:PATH---存储程序运行默认的搜索路径
运行一个程序的时候,如果没有指定程序路径,只有程序名称,则shell会去PATH环境变量保存的路径中去找这个程序,如果没有找到,就报错。
没有这个命令,如果将我们自己的程序所在路径加入到PATH环境变量中,则这个程序就可以直接运行了
代码操作:
char *getenv(char *key);//通过环境变量名称获取环境变量内容
在终端中运行的程序,父进程都是bash,也就是shell程序;
一个终端打开,默认运行一个程序-shell程序-命令行解释器,当shell捕捉到字符串,就回到PATH环境变量指定的路径下去找到对应名称的程序,
进而执行这个程序完成功能(其实shell程序创建了一个进程,让个进程去调度我们要运行的程序)
---在终端中运行程序所创建的进程都是shell创建的,也就是运行的程序进程的都进程就是shell
ps -ef
获取环境变量2种方式:
环境变量结果:
main函数的三个参数:int main(int argc,char *argv[],char *env[])
argc是程序运行参数的个数
argv用于执行程序中各个环境变量的一个字符串指针数组,保存程序运行参数
./env -l -a [./env]第0个参数 [-l]就是第一个参数 [-a] 就是第二个参数
env[] 适用于指向程序中各个环境变量的一个字符串指针数组
extern char **environ; 库中的全局变量,每个节点指向一个环境变量,但是使用时需要声明,告诉编译器有这个变量。
设置环境变量:setenv()/putenv()