OS
介绍和例子
-
希望操作系统能干嘛
- 共享数据文件
- 安全权限访问
- 支持不同编译器
- 执行不同任务
- 满足大大小小需求
- 语言大部分都是从操作系统提取出来的,可以满足在操作系统对系统的调用操作
-
设计思想
- 操作系统下直接是硬盘,接近硬盘底层运行
- 只有一个内核来管理数据,第一个启动,帮助管理应用程序,主要关注内核内部的运作
- 内核影响文件系统,找到磁盘文件,访问权限由内核决定
- 内核将进程服务进行管理,内存分配,内存复用
- 内核系统调用有点像程序进行的函数调用,跳入内核,并执行内核的系统调用例如打开文件
fd = open(" out ", 1)
,分配进程pid = fork()
,内核有特权,可以访问所有硬盘被保护的文件进行修改和查询 - 通过网络栈连接到操作系统
OS基础学习
寄存器
功能:存储二进制代码
寄存器的用途:
1.可将寄存器内的数据执行算术及逻辑运算。
2.存于寄存器内的地址可用来指向内存的某个位置,即寻址。
3.可以用来读写数据到电脑的周边设备。
程序:
- 存储在磁盘上的静态文件
进程:
- 程序的动态状态,系统进行调度的最小单元
- 系统进行资源分配和调度的一个独立单元,是系统中并发执行的单位
- 运行中的程序,程序本身是没有生命周期的,它只是存在于磁盘上面的一些指令(也可能是一些静态数据),是操作系统让这些字节运行起来,让程序发挥作用
- 关于进程的分析的分析提到,为了让一段程序认为自己独享 CPU,操作系统需要实现时分共享的功能,包括低层的上下文切换(内核 (操作系统的核心)在 CPU 上对进程或者线程进行切换。),以及高层的调度策略,操作系统会为每个程序记录与其有关的信息。正在运行的程序本身加上与其有关的信息,构成了一个进程
线程
- CPU调度的最小单元
- 线程是进程的一个实体,也是CPU调度和分派的最小单位,它是比进程更小的能独立运行的基本单位,有时被称为轻权进程或轻量级进程
时分共享
-
操作系统允许资源由一个实体使用一小段时间,然后另外一个实体使用小段时间,这样实现资源(CPU或网络连接)可以被多人共享
-
操作系统如何做到制造一个CPU运行多个进程的假象:
- 虚拟化CPU:让一个进程只运行一个时间片,然后切换其他进程(时分共享CPU技术)
- 潜在开销就是性能损失,如果CPU必须共享,每个进程运行就会变慢一些
- 上下文切换(内核 (操作系统的核心)在 CPU 上对进程或者线程进行切换。),就是当进程重新开始执行的时候,恢复相关的计算机环境,不管是内存中的一个临时结果,内存的临时空间,或者其他计算机原件。计算机靠程序状态寄存器来保存这部分状态。
- 上下文切换时需要将寄存器(包括变量,程序计数器,栈指针)的值保存到内存中,恢复现场时把对应的值设置回寄存器中
- 宏观上并行,微观上串行(一次传输一个数据)
空分共享
- 资源在空间上被划分给希望使用它的人
- 如磁盘空间,一旦一块内存位置分配给一个文件,则在该文件没有被删除前,操作系统无法将该空间分配给其他文件
进程API
- 创建
- 销毁:停止失控进程的接口
- 等待
- 其他控制:大多数操作系统提供某种方法来暂停进程,然后恢复执行
- 状态:获得有关进程的状态信息,如运行多长时间,处于什么状态
进程状态
-
运行(running):正在执行指令
-
就绪(ready):程序已准备好运行,由于某种原因,OS选择不在此时运行
- 运行和就绪之间存在调度和取消调度的关系
-
阻塞(blocked):在阻塞状态下,一个进程执行了某种操作,直到发生其他事件时才会准备运行。一个常见的例子是,当进程向磁盘发起I/O请求时,它会被阻塞,因此其他进程可以使用处理器。
- 发起IO,会调用系统调用,此时,操作系统会发起中断,让程序从用户态切换到内核态,当前执行流会调用内核相关的函数,直到再次切换到用户态。
- 而在切换用户态到内核态中,此时对于上层的进程来看就是阻塞状态,可以用来处理其他程序,直到 I/O 完成操作,等待刚才所执行的进程执行完毕,通过中断告知CPU ,再将控制流返回 io 请求的进程。大部分情况CPU分片执行的时间是低于磁盘 io 的读写时间
-
除了运行、就绪和阻塞之外,还有其他一些进程可以处于的状态。有时候系统会有一个初始(initial)状态,表示进程在创建时处于的状态。另外,一个进程可以处于已退出但尚未清理的最终(final)状态(在基于UNIX的系统中,这称为僵尸状态)。这个最终状态非常有用,因为它允许其他进程(通常是创建进程的父进程)检查进程的返回代码,并查看刚刚完成的进程是否成功执行(通常,在基于UNIX的系统中,程序成功完成任务时返回零,否则返回非零)。完成后,父进程将进行最后一次调用(例如,wait()),以等待子进程的完成,并告诉操作系统它可以清理这个正在结束的进程的所有相关数据结构。
-
僵尸进程:当子进程比父进程先退出而父进程又没有调用wait()或waitpid()函数调用释放子进程资源那这样子进程就会成为僵尸进程;当父进程先退出,系统init会接管子进程,成为它的父进程,由它来释放子进程资源
程序如何转化为进程:
- 代码+静态数据在磁盘
- 加载到内存
- 加载到进程的地址空间
- 将代码和所有静态数据(例如初始变量)加载(取得磁盘上的程序,将它放在进程的地址空间)到内存中,加载到进程的地址空间中。早期(加载过程尽早完成)现代(懒性加载)
- 为运行时栈分配内存并初始化(栈存储:局部变量、函数参数、返回地址)run-time stack
- 为程序的堆分配一些内存(动态申请的变量,数据结构需要,可能随着程序运行堆越来越大)-- malloc()
- 每个进程都有3个打开的文件描述符(标准输入、标准输出、错误),进行I/O相关的其他工作
- 启动程序 -- 跳转到入口main() ,os移交CPU控制权到新进程
-
比如在程序运行中,删除电脑内的文件夹,系统提示正在运行不让删除。这就表示磁盘的内容被加载到内存中了,被使用中。