进程概念 ***
冯诺依曼体系结构:现代计算机的硬件结构
五大硬件单元:
输入设备:键盘等
输出设备:显示器
存储器:内存:30Gbps
硬盘:机械 200MB/s 固态 3~400MB/s
运算器:cpu---时钟振荡周期----机器指令周期
主频越高,每秒钟能够处理的指令更多
控制器:
硬件结构决定软件行为:数据都是围绕内存流动的
输入设备获取数据存储到内存中,cpu处理数据,是从内存中获取数据,
运算完毕放入内存,输出设备从内存获取数据
所有设备都是围绕内存工作
操作系统:
操作系统=内核+应用
操作系统的功能:使计算机使用起来更好
操作系统的定位:一款做管理的软件,对下管理软硬件资源,
对上提供良好的环境
操作系统如何管理软硬件?
先将被管理者描述起来,然后组织起来进行管理
**库函数和系统调用接口的关系:
库函数封装了系统调用接口,上下级的调用关系
进程:运行中的程序
程序:存储在硬盘中的可执行程序文件
操作系统如何管理进程?
站在操作系统角度:进程就是操作系统对进程的描述 pcb(windows下 进程控制块)
task_struct(linux下进程控制块)
tasck_struct内容分类
标识符(PID),进程状态,优先级,内存指针,
上下文数据,程序计数器,IO状态信息,记账信息
进程的切换调度:cpu的分时技术----时间片
进程查看:
ls /proc/ , ps -ef , ps aux , top , getpid
进程创建:
fork() 操作系统提供的创建进程的接口
fork通过复制父进程创建一个新的子进程,
复制:复制的是父进程的pcb,意味着子进程跟父进程代码段和数据段指向的是
同一块内存区域(数据跟代码运行的完全一样),并且子进程拷贝了程序计数器
和上下文数据,所以当前的子进程是从子进程创建成功的下一步指令开始的
父子进程代码共享,数据独有
返回值:在父进程中,返回子进程pid>0;在子进程中返回0
因为父子进程返回值不同,所以通过返回值对父子进程做代码分流
perror:打印上一个系统调用的错误原因
进程状态:
阻塞,运行,就绪
linux下的进程状态:
运行 R
可中断睡眠 S
不可中断睡眠 D
停止 T
僵尸 Z \死亡 \追踪等
僵尸进程:处于僵尸状态的进程
危害:资源泄露
产生:子进程先于父进程退出,操作系统通知父进程,但是没联系上父进程
然而操作系统不敢擅自释放子进程的资源,一旦释放,就无法保存子
进程退出原因,因此子进程就成了僵尸进程.
处理: 退出父进程
孤儿进程:父进程先于子进程退出,子进程就称为孤儿进程,子进程到后台进行,
孤儿进程的父亲进程将变为1号init进程,并且孤儿进程退出,不会产
生僵尸进程
守护进程/精灵进程:特殊的孤儿进程
进程优先级:数字--让操作系统运行的更加合理
功能: 决定cpu资源的优先分配权
查看:ps -l
PRI NI
优先级无法直接修改,但是可以通过设置NI的值进而对优先级做出设置
nice取值范围: -20~19
PRI=PRI+NI
nice renice
renice -n 10 -p 5251 //把5251的niece设置为10
进程相关概念: 竞争性 独立性 并行 并发
环境变量:用于设置系统运行环境参数的变量
高效,规范
查看:env
set
echo $pwd
设置:export myval=1000
删除:unset myval
作用:让程序运行更加高效,因为环境变量具有**全局特性**
获取一个环境变量
char* getenv(const char* name )
main第三个参数
extern char **environ
程序地址空间:每个程序都有自己的程序地址空间,我们所说的程序地址空间,实际上是
一个进程的虚拟地址空间,目的是为了告诉进程,每个进程都有一个完整的连续的
内存,但是真正一个进程使用的内存经过页表映射后可能只使用很少一部分物理内存
进程虚拟地址空间:进程对内存的描述mm_struct
页表:记录虚拟地址与物理地址映射关系,并且对内存进行访问控制
分页式管理:提高内存利用率,内存访问控制
内存地址:内存的编号
写时拷贝技术:修改子进程数据的时候,才在内存中重新找一个地址存放子进程
提高创建子进程效率
《linux内核实现与设计》
进程调度:cpu调度进程的就是调度进程
大O(1)调度算法
进程控制 **
进程创建:
fork()
复制:复制的是pcb---代码共享,数据独有(代码段特性:只读)
返回值:返回值<0时出错 ,父进程返回子进程pid>0, 子进程返回0
vfork()--父子进程公用同一块虚拟地址空间
子进程先运行,并且是子进程退出或子进程程序替换运行另一段
程序后,父进程才开始运行
进程终止:
终止场景:正常终止,结果符合预期;正常终止,结果不符合预期;异常终止
终止方式:main中return exit() _exit()
exit() 库函数 做了一系列收尾操作后才释放资源(包括刷新缓冲区)
_exit() 系统调用 直接释放资源,退出进程
进程等待:等待子进程的退出
等待子进程退出的原因:避免产生僵尸进程
因为子进程什么时候退出,父进程不知道,因此创建子进程后
一直等待子进程退出
wait waitpid
阻塞:为了完成操作发起调用,但是当前如果不具备完成条件
则一直等待,直到完成操作
非阻塞:为了完成操作发起调用,但时如果不具备完成条件,则立即报错返回
pid_t waitpid(pid_t pid,int* status,int options)
pid:
>0 等待指定pid 的子进程
-1 等待任意一个子进程
程序替换: 替换进程所运行的程序(程序在内存中)
将代码段虚拟地址经过页表所映射的物理地址区域(代码在内存中的位置)
替换成另一块内存中代码的位置
新的程序有自己运行的数据,意味着虚拟地址空间中不仅代码段映射位置改变
并且数据段也需要重新开始初始化,映射到新程序数据段的位置
(fork创建子进程使用写时拷贝技术的目的:就是为了防止这种情况下空间的
白白开辟,以及数据的拷贝成本)
目的:为了让子进程不跟父进程做相同的事
exec函数族:
execl execlp execle
execv execvp execve
l和v区别:l 命令行参数平铺,以NULL结尾
v 命令行参数使用字符串指针数组
l lp le区别:l 是需要传递可执行程序文件全路径名
lp 只需传递文件名
le 传递文件全路径,并且可以自定义环境变量